2014-07-14 192 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