【问题标题】:Sum on case expression when working with dates使用日期时对大小写表达式求和
【发布时间】:2015-08-03 02:01:55
【问题描述】:

我正在寻找一个视图,它将以以下格式输出数据

AgedPeriod   BillValue  Status
<1            35000     Outstanding 
1-3           23386     Outstanding 
3-6           5000      Outstanding

我可以使用下面的代码将每个 case 语句求和到一个新列中,我可以在上面列出的 AgedPeriod 之后命名列标题,但即使 SUMS 是正确的格式是错误的我想要代码下面嵌套在另一个不必按 b.BILL_DATE 分组的 CASE 语句中,因为与账单日期分组违背了我的 SUM 的目的。使用另一个 CASE 语句的所有尝试总是将 b.BILL_DATE 带出 SUM 并进入需要对其进行分组的 WHEN 条件。

SELECT 
SUM(CASE WHEN (b.BILL_DATE <= GetDate() 
             AND b.BILL_DATE >= DateAdd(mm,-1, GetDate())) 
        THEN b.OUTSTANDING END),
SUM(CASE WHEN (b.BILL_DATE <= DateAdd(mm,-1, GetDate()) 
              AND b.BILL_DATE >= DateAdd(mm,-3, GetDate())) 
         THEN b.OUTSTANDING END),
SUM(CASE WHEN (b.BILL_DATE <= DateAdd(mm,-3, GetDate()) 
              AND b.BILL_DATE >= DateAdd(mm,-6, GetDate())) 
         THEN b.OUTSTANDING END) 
FROM  dbo.Tables

我知道这可能无法通过我目前采取的路线实现,但有没有其他方法可以SUM 每个时间段的未结金额?我可以处理状态栏(那里不需要建议)

我添加了一个表格和一些示例数据,并留下了一个查询以显示我希望如何拆分数据,但它希望它的格式如上(在一列中)

Example on Sql Fiddle

谢谢

【问题讨论】:

  • 哪个 dbms? (例如 DateAdd 和 GetDate 是特定于产品的。)
  • 如果您能向我们提供更详细的示例数据、表定义和预期结果,那么我们将能够提供更好的帮助
  • @jarlh 这是 SSMS 和 T-SQL
  • @Jeremy C 我试图简化这一点,以免混淆。预期的结果将如上。我将在主帖中添加一个链接以帮助提供更多详细信息。谢谢
  • 如果三个年龄段是固定的,那么您可以使用 UNION 来代替。

标签: sql sql-server date sum case


【解决方案1】:

您需要group by 而不是条件聚合。你想要的查询是这样的:

SELECT (CASE WHEN b.BILL_DATE >= DateAdd(month,-1, GetDate())
             THEN '<1'
             WHEN b.BILL_DATE >= DateAdd(month, -3, GetDate())
             THEN '1-3'
             WHEN b.BILL_DATE >= DateAdd(month, -6, GetDate())
             THEN '3-6'
             ELSE '6+'
        END) as AgedPeriod,
       SUM(Outstanding)
FROM dbo.Tables b
WHERE b.BILL_DATE <= GetDate()
GROUP BY (CASE WHEN b.BILL_DATE >= DateAdd(month,-1, GetDate())
               THEN '<1'
               WHEN b.BILL_DATE >= DateAdd(month, -3, GetDate())
               THEN '1-3'
               WHEN b.BILL_DATE >= DateAdd(month, -6, GetDate())
               THEN '3-6'
               ELSE '6+'
          END);

注意事项:

  • 组由CASE 语句定义。因为这是按顺序计算的,所以可以简化逻辑。
  • 通用条件b.BILL_DATE &lt;= GetDate() 移至WHERE 子句。
  • 我添加了超过六个月的额外条件。您似乎不想忽略这些。
  • 我不知道最后一列应该是什么。

【讨论】:

  • 我可以看到你用这个去哪里,但即使它在 BILL_DATE 拆分 GROUP BY 我得到错误 Column 'BILL.BILL_DATE' is invalid in the select list 因为它不包含在任何一个聚合函数或 GROUP BY 子句。我期待不同。我将在主帖中添加一个链接以帮助提供更多详细信息。谢谢
  • 在实现了这两种方法之后,我发现这是最好的 Gordon。我错过了别名错字。非常感谢
【解决方案2】:

您可以使用 subqueryCTE 执行 case when 语句,然后返回基表以获得未完成列的 sum,如下所示:

SELECT a.AgedPeriod
    ,sum(t1.Outstanding) BillValue
    ,a.[Status]
FROM dbo.Bill t1
JOIN (
    SELECT (
            CASE 
                WHEN b.BILLDATE >= DateAdd(month, - 1, GetDate())
                    THEN '<1'
                WHEN b.BILLDATE >= DateAdd(month, - 3, GetDate())
                    THEN '1-3'
                WHEN b.BILLDATE >= DateAdd(month, - 6, GetDate())
                    THEN '3-6'
                ELSE '6+'
                END
            ) AS AgedPeriod
        ,b.[ID]
        ,'Outstanding' [Status]
    FROM dbo.Bill b
    WHERE b.BILLDATE <= GetDate()
    ) a ON a.[ID] = t1.[ID]
GROUP BY a.AgedPeriod
    ,a.[Status]

希望这会有所帮助!这是一个 SQL Fiddle 演示:

SQL Fiddle Solution Demo

【讨论】:

  • 这正是我想要的。我想。您的 SQL Fiddle 成型良好,早期的重写看起来不错。谢谢@Nepali Rookie
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
相关资源
最近更新 更多