多个案例陈述总和

时间:2014-07-14 17:20:05

标签: sql sql-server

所以我在表格中有以下数据列:

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失败,则工单自动评定为&#34; RED&#34;。对于测试1,2和3,它们被评为&#34; GREEN&#34;如果他们通过所有3,&#34; YELLOW&#34;如果他们通过任何2,&#34; ORANGE&#34;如果他们只通过1,并且&#34; RED&#34;如果他们没有通过(或如果他们没有通过测试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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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'