所以我在表格中有以下数据列:
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
答案 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'