2014-07-14 194 views
1

所以我有數據表中的下列列:多個case語句和

workordernum | targstart | targfinish | schedstart | schedfinish | actstart | actfinish 

我需要返回以下結果集:

rating | count 

樣品:

RED | 0 
ORANGE | 1 
YELLOW | 4 
GREEN | 38 

該評級是基於以下條件:

acfinish <= targfinish (test 0) 
actstart <= schedstart (test 1) 
actfinish <= schedfinish (test 2) 
targstart <= (a calculated column called "halflife") (test 3) 

如果測試0失敗,則工單將自動評爲「紅色」。對於測試1,測試2和測試3,如果它們全部通過了3,則它們被評爲「綠色」,如果它們通過2,則通過「黃色」;如果通過1,則通過「橙色」;如果通過,則通過「如果他們測試失敗0)

在SQL查詢中處理這個問題的最佳方法是什麼?我當前的查詢使用CASE語句來評估每個測試爲1或0,但是我需要總結它們並做一些IF語句來處理測試0.我的猜測是我要麼過度複雜化或者缺乏可能幫助的一點SQL函數的知識。

任何和所有的幫助表示感謝,並提前感謝您!


編輯1:當前的代碼(如需要)

SELECT 
    wo.wonum, 
    wo.targstartdate, 
    wo.targcompdate, 
    wo.schedstart, 
    wo.schedfinish, 
    wo.actstart, 
    wo.actfinish, 
    FLOOR(
     DATEDIFF(
      DAY, 
      targstartdate, 
      CASE pm.frequnit 
       WHEN 'YEARS' THEN DATEADD(YEAR,pm.frequency,wo.targstartdate) 
       WHEN 'MONTHS' THEN DATEADD(MONTH,pm.frequency,wo.targstartdate) 
       WHEN 'WEEKS' THEN DATEADD(WEEK,pm.frequency,wo.targstartdate) 
       WHEN 'DAYS' THEN DATEADD(DAY,pm.frequency,wo.targstartdate) 
       ELSE targstartdate 
      END 
     ) 
    ) AS halflife, 
    CASE 
     WHEN wo.actfinish < wo.targcompdate THEN 1 
     ELSE 0 
    END AS test0, 
    CASE 
     WHEN wo.actstart <= wo.schedstart THEN 1 
     ELSE 0 
    END AS test1, 
    CASE 
     WHEN wo.actfinish <= wo.schedfinish THEN 1 
     ELSE 0 
    END AS test2, 
    CASE 
     WHEN wo.schedstart <= DATEADD(DAY,FLOOR(DATEDIFF(DAY,wo.targstartdate,CASE pm.frequnit WHEN 'YEARS' THEN DATEADD(YEAR,pm.frequency,wo.targstartdate) WHEN 'MONTHS' THEN DATEADD(MONTH,pm.frequency,wo.targstartdate) WHEN 'WEEKS' THEN DATEADD(WEEK,pm.frequency,wo.targstartdate) WHEN 'DAYS' THEN DATEADD(DAY,pm.frequency,wo.targstartdate) ELSE wo.targstartdate END)),wo.targstartdate) THEN 1 
     ELSE 0 
    END AS test3 
FROM 
    workorder AS wo 
    LEFT OUTER JOIN pm ON pm.pmnum=ISNULL(wo.pmnum,(SELECT pmnum FROM workorder WHERE wonum=wo.parent)) 
WHERE 
    wo.status IN (SELECT value FROM synonymdomain WHERE domainid='WOSTATUS' AND maxvalue IN ('COMP','CLOSE','HISTEDIT')) 
    AND wo.istask=0 
    AND DATEDIFF(MONTH,wo.actfinish,GETDATE())=1 
    AND wo.worktype='PM' 


編輯2:

我使用下面的思想實驗0返回1或0,所以我乘上更新我的代碼通過測試1,測試2和測試3的總和,那樣它將總是返回0,如果那個失敗的話。然後我用CASE語句用適當的顏色標註它。但是,現在我得到一份工作單號碼和他們的評級列表,我需要將它調整到一個評級列表和他們的計數!

SELECT 
    wo.wonum, 
    CASE 
     (CASE 
      WHEN wo.actfinish < wo.targcompdate THEN 1 
      ELSE 0 
     END * 
     (CASE 
      WHEN wo.actstart <= wo.schedstart THEN 1 
      ELSE 0 
     END + 
     CASE 
      WHEN wo.actfinish <= wo.schedfinish THEN 1 
      ELSE 0 
     END + 
     CASE 
      WHEN wo.schedstart <= DATEADD(DAY,FLOOR(DATEDIFF(DAY,wo.targstartdate,CASE pm.frequnit WHEN 'YEARS' THEN DATEADD(YEAR,pm.frequency,wo.targstartdate) WHEN 'MONTHS' THEN DATEADD(MONTH,pm.frequency,wo.targstartdate) WHEN 'WEEKS' THEN DATEADD(WEEK,pm.frequency,wo.targstartdate) WHEN 'DAYS' THEN DATEADD(DAY,pm.frequency,wo.targstartdate) ELSE wo.targstartdate END)),wo.targstartdate) THEN 1 
      ELSE 0 
     END)) 
     WHEN 3 THEN 'GREEN' 
     WHEN 2 THEN 'YELLOW' 
     WHEN 1 THEN 'ORANGE' 
     WHEN 0 THEN 'RED' 
     ELSE 'RED' 
    END 
FROM 
    workorder AS wo 
    LEFT OUTER JOIN pm ON pm.pmnum=ISNULL(wo.pmnum,(SELECT pmnum FROM workorder WHERE wonum=wo.parent)) 
WHERE 
    wo.status IN (SELECT value FROM synonymdomain WHERE domainid='WOSTATUS' AND maxvalue IN ('COMP','CLOSE','HISTEDIT')) 
    AND wo.istask=0 
    AND DATEDIFF(MONTH,wo.actfinish,GETDATE())=1 
    AND wo.worktype='PM' 


最後編輯: 只是爲了保持完整性,我已經把下面的最終代碼:

SELECT rating,count(*) 
FROM 
(SELECT 
    CASE 
     (CASE 
      WHEN wo.actfinish < wo.targcompdate THEN 1 
      ELSE 0 
     END * 
     (CASE 
      WHEN wo.actstart <= wo.schedstart THEN 1 
      ELSE 0 
     END + 
     CASE 
      WHEN wo.actfinish <= wo.schedfinish THEN 1 
      ELSE 0 
     END + 
     CASE 
      WHEN wo.schedstart <= DATEADD(DAY,FLOOR(DATEDIFF(DAY,wo.targstartdate,CASE pm.frequnit WHEN 'YEARS' THEN DATEADD(YEAR,pm.frequency,wo.targstartdate) WHEN 'MONTHS' THEN DATEADD(MONTH,pm.frequency,wo.targstartdate) WHEN 'WEEKS' THEN DATEADD(WEEK,pm.frequency,wo.targstartdate) WHEN 'DAYS' THEN DATEADD(DAY,pm.frequency,wo.targstartdate) ELSE wo.targstartdate END)),wo.targstartdate) THEN 1 
      ELSE 0 
     END)) 
     WHEN 3 THEN 'GREEN' 
     WHEN 2 THEN 'YELLOW' 
     WHEN 1 THEN 'ORANGE' 
     WHEN 0 THEN 'RED' 
     ELSE 'RED' 
    END AS rating 
FROM 
    workorder AS wo 
    LEFT OUTER JOIN pm ON pm.pmnum=ISNULL(wo.pmnum,(SELECT pmnum FROM workorder WHERE wonum=wo.parent)) 
WHERE 
    wo.status IN (SELECT value FROM synonymdomain WHERE domainid='WOSTATUS' AND maxvalue IN ('COMP','CLOSE','HISTEDIT')) 
    AND wo.istask=0 
    AND DATEDIFF(MONTH,wo.actfinish,GETDATE())=1 
    AND wo.worktype='PM' 
) AS worating 
GROUP BY rating 
+0

你可以使用'CASE'語句來添加當前查詢嗎?我認爲遵守/適應比通過所提出的規則閱讀要容易。 –

+0

當然!給我第二個編輯帖子 –

+0

已添加SQL代碼 –

回答

3

可以檢查你的查詢執行的測試,如與總和以下?

SELECT 
    wonum, 
    targstartdate, 
    targcompdate, 
    schedstart, 
    schedfinish, 
    actstart, 
    actfinish, 
    halflife, 
    CASE 
     WHEN test0 + test1 + test2 + test3 >= 3 THEN 'RED' 
     WHEN test0 + test1 + test2 + test3 = 2 THEN 'ORANGE' 
     WHEN test0 + test1 + test2 + test3 = 1 THEN 'YELLOW' 
     WHEN test0 + test1 + test2 + test3 = 0 THEN 'GREEN' 
    END AS Flag 
FROM 
    (
    SELECT .... yourquery 
) s 

編輯1:忘了補充一點,在你的查詢,你應該評估的主要情況(TEST0,對吧?)爲4,而不是1,即

CASE 
    WHEN wo.actfinish < wo.targcompdate THEN 4 
    ELSE 0 
END AS test0, 

這樣一來,任何測試零點自動失效總計爲紅色級別總計。

編輯2:將CASE語句添加到GROUP BY。如果您只想查看語句和計數,則此查詢應執行您正在查找的內容。

SELECT 
    CASE 
     WHEN test0 + test1 + test2 + test3 >= 3 THEN 'RED' 
     WHEN test0 + test1 + test2 + test3 = 2 THEN 'ORANGE' 
     WHEN test0 + test1 + test2 + test3 = 1 THEN 'YELLOW' 
     WHEN test0 + test1 + test2 + test3 = 0 THEN 'GREEN' 
    END AS Rating, 
    COUNT(wonum) AS TotalRecords 
FROM 
    (
    SELECT .... yourquery 
) s 

GROUP BY 
    CASE 
     WHEN test0 + test1 + test2 + test3 >= 3 THEN 'RED' 
     WHEN test0 + test1 + test2 + test3 = 2 THEN 'ORANGE' 
     WHEN test0 + test1 + test2 + test3 = 1 THEN 'YELLOW' 
     WHEN test0 + test1 + test2 + test3 = 0 THEN 'GREEN' 
    END 
+0

該代碼與我剛剛更新的代碼類似(我在等待答案時正在處理此問題)。它給出了工單的正確評分,但沒有對每種類型進行計數 –

+0

將標記CASE語句添加到GROUP BY子句,然後將COUNT(wonum)添加到您的查詢中...我將更新以顯示示例 – AHiggins

+0

上面的示例 - 我除去了額外的列,只留下了CASE語句和COUNT(),然後將CASE語句複製到了GROUP BY子句中。 – AHiggins

1

我將您的案例移至子選擇。然後在主選擇中返回顏色。

SELECT 
    wo.wonum, 
    wo.targstartdate, 
    wo.targcompdate, 
    wo.schedstart, 
    wo.schedfinish, 
    wo.actstart, 
    wo.actfinish, 
    FLOOR(
     DATEDIFF(
      DAY, 
      targstartdate, 
      CASE pm.frequnit 
       WHEN 'YEARS' THEN DATEADD(YEAR,pm.frequency,wo.targstartdate) 
       WHEN 'MONTHS' THEN DATEADD(MONTH,pm.frequency,wo.targstartdate) 
       WHEN 'WEEKS' THEN DATEADD(WEEK,pm.frequency,wo.targstartdate) 
       WHEN 'DAYS' THEN DATEADD(DAY,pm.frequency,wo.targstartdate) 
       ELSE targstartdate 
      END 
     ) 
    ) AS halflife, 
    CASE WHEN wo.test0 = 0 or (wo.test1 + wo.test2+ wo.test3) = 0 then 'RED' 
     WHEN wo.test1 + wo.test2 + wo.test3 = 3 then 'GREEN' 
     WHEN wo.test1 + wo.test2 + wo.test3 = 2 then 'YELLOW' 
     WHEN wo.test1 + wo.test2 + wo.test3 = 1 then 'ORANGE' 
     ELSE '' 
    END AS Rating 
FROM 
    (select * , CASE WHEN wo.actfinish < wo.targcompdate THEN 1 ELSE 0 END AS test0, 
    CASE WHEN wo.actstart <= wo.schedstart THEN 1 ELSE 0 END AS test1, 
    CASE WHEN wo.actfinish <= wo.schedfinish THEN 1 ELSE 0 END AS test2, 
    CASE 
     WHEN wo.schedstart <= DATEADD(DAY,FLOOR(DATEDIFF(DAY,wo.targstartdate,CASE pm.frequnit WHEN 'YEARS' THEN DATEADD(YEAR,pm.frequency,wo.targstartdate) WHEN 'MONTHS' THEN DATEADD(MONTH,pm.frequency,wo.targstartdate) WHEN 'WEEKS' THEN DATEADD(WEEK,pm.frequency,wo.targstartdate) WHEN 'DAYS' THEN DATEADD(DAY,pm.frequency,wo.targstartdate) ELSE wo.targstartdate END)),wo.targstartdate) THEN 1 
     ELSE 0 
    END AS test3 from workorder) AS wo 
    LEFT OUTER JOIN pm ON pm.pmnum=ISNULL(wo.pmnum,(SELECT pmnum FROM workorder WHERE wonum=wo.parent)) 
WHERE 
    wo.status IN (SELECT value FROM synonymdomain WHERE domainid='WOSTATUS' AND maxvalue IN ('COMP','CLOSE','HISTEDIT')) 
    AND wo.istask=0 
    AND DATEDIFF(MONTH,wo.actfinish,GETDATE())=1 
    AND wo.worktype='PM' 
+0

我試着運行該代碼,它吐出錯誤(我相信與FROM代碼有關(應該有一個逗號或什麼東西靠近SELECT * ??) –

+0

@ D.R。是的我錯過了逗號* – SQLChao