2015-01-21 15 views
1

我目前有两个日期字段,effective_date和invoice_date。我找到了两者的最近日期,然后计算出此日期和今天之间的天数(或者报告运行时间)。使用这个,我然后在'老化'列中创建一个标签,将结果分组为年龄段。我目前的代码是这样的:在SQL中查询有效绑定DATEDIFF(DAY)的方法(带有预计算)

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 当前命令发生严重错误。如果有的话,结果应该被丢弃。

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

回答

1

试试这个,我想它会稍微更快,更方便读者:

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 
+0

神奇。真的很干净 - 太棒了!关于max()方法的任何想法与使用case语句来标识初始DATEDIFF? – chris1982 2015-01-21 11:06:40

+0

@ chris1982为了使用max,您需要将2列工作到一个表中并使用另一个跨应用。只有2列进行比较时,案例解决方案更加清晰 – 2015-01-21 11:40:07