查询 SQL 中带状 DATEDIFF(DAY) 的有效方式(使用预计算)

Query efficient way of banding DATEDIFF(DAY) in SQL (with a pre-calculation)

我目前有两个日期字段,effective_date 和 invoice_date。我正在查找这两个日期中的最近日期,然后计算出该日期与今天(或报告为 运行 时)之间的天数。然后我使用它在 'Ageing' 列中创建一个标签,以将结果分组到年龄段中。我当前的代码是这样的:

SELECT TOP 500 

'Ageing' = CASE WHEN DATEDIFF(DD,
                CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
                     THEN tbis.invoice_date_key
                     ELSE tbis.effective_date_key
                END, GETDATE()) < 0 THEN 'Prebill'

                WHEN DATEDIFF(DD,
                CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
                     THEN tbis.invoice_date_key
                     ELSE tbis.effective_date_key
                END, GETDATE()) BETWEEN 0 AND 29 THEN '<30 Days'

                WHEN DATEDIFF(DD,
                CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
                     THEN tbis.invoice_date_key
                     ELSE tbis.effective_date_key
                END, GETDATE()) BETWEEN 30 AND 59 THEN '30+ Days'

                WHEN DATEDIFF(DD,
                CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
                     THEN tbis.invoice_date_key
                     ELSE tbis.effective_date_key
                END, GETDATE()) BETWEEN 60 AND 89 THEN '60+ Days'

                WHEN DATEDIFF(DD,
                CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
                     THEN tbis.invoice_date_key
                     ELSE tbis.effective_date_key
                END, GETDATE()) BETWEEN 90 AND 119 THEN '90+ Days'

                WHEN DATEDIFF(DD,
                CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
                     THEN tbis.invoice_date_key
                     ELSE tbis.effective_date_key
                END, GETDATE()) BETWEEN 120 AND 179 THEN '120+ Days'

                WHEN DATEDIFF(DD,
                CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
                     THEN tbis.invoice_date_key
                     ELSE tbis.effective_date_key
                END, GETDATE()) BETWEEN 180 AND 364 THEN '180+ Days'

                WHEN DATEDIFF(DD,
                CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
                     THEN tbis.invoice_date_key
                     ELSE tbis.effective_date_key
                END, GETDATE()) >= 365 THEN '365+ Days'
                ELSE NULL
                END

                FROM [transaction] tbis

这种方法工作正常,但我目前只查看 150,000 条记录。很快这将是 运行 潜在的数百万条记录。

因此,我想看看是否可以改进它的编写方式。我已经使用另一个 SELECT 和 MAX() 方法查看了下面的内容:

DATEDIFF(DAY, (SELECT   MAX(v)
                       FROM     ( VALUES ( t.effective_date_key), ( t.invoice_date_key) ) AS value (v)
                      ), GETDATE())

这在单独使用时效果很好 - 获取每条记录的旧天数。但是当嵌套到上面的 case 语句中时,它会产生以下错误:

消息 0,级别 11,状态 0,第 0 行 当前命令发生严重错误。结果,如果有的话,应该被丢弃。 消息 0,级别 20,状态 0,行 0 当前命令发生严重错误。结果,如果有的话,应该被丢弃。

任何关于如何以更有效的方式实现我的目标的想法都会很棒。或者,也许我现有的案例陈述是最好的方法?

试试这个,我想它会稍微快一点,更 reader 友好:

SELECT TOP 500 
'Ageing' = 
  CASE WHEN x.datedif < 0 THEN 'Prebill'
       WHEN x.datedif < 30 THEN '<30 Days'
       WHEN x.datedif < 60 THEN '30+ Days'
       WHEN x.datedif < 90 THEN '60+ Days'
       WHEN x.datedif < 120 THEN '90+ Days'
       WHEN x.datedif < 180 THEN '120+ Days'
       WHEN x.datedif >= 180 THEN '180+ Days'
       ELSE NULL
  END
FROM [transaction] tbis
CROSS APPLY
(
    SELECT 
      DATEDIFF(DD,
        CASE WHEN tbis.invoice_date_key > tbis.effective_date_key
        THEN tbis.invoice_date_key
        ELSE tbis.effective_date_key
      END, GETDATE()) datedif
) x