2015-01-21 18 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