[英]SQL query count occurrences then group by day but also fill missing days
我有一个名为diseaseScores
的表,该表具有计算结果。 每小时计算一次跑步成绩( currentScore
)。 该查询的目的是按小时( obsDate
)将小时分数obsDate
,然后计算跑步分数处于较高水平的numberOfhours
。 高大于16( currentScore > 16
)。
到目前为止,我的查询是:
SELECT
DATEADD(DAY, 0, DATEDIFF(day, 0, obsDate)) AS obsDate,
(CASE
WHEN count(id) > 12 THEN count(id)
ELSE 0
END) numOfHoursAtHigh
FROM
diseaseScores
WHERE
diseaseID = 2
AND siteID = 72160
AND numOfRotationYears = 3
AND currentScore > 16
AND month(obsDate) IN (6)
GROUP BY
DATEADD(DAY, 0, DATEDIFF(day, 0, obsDate))
ORDER BY
DATEADD(DAY, 0, DATEDIFF(day, 0, obsDate));
该查询返回每月13天的结果。 我希望填补空白,所以我每个月的每一天都有一个记录。 间隙需要将numOfHoursAtHigh
结果numOfHoursAtHigh
0。
我怎样才能做到这一点? 这是针对SQL Server 2008 +
返回的结果集为:
2016-06-04 00:00:00.000 0
2016-06-05 00:00:00.000 23
2016-06-06 00:00:00.000 23
2016-06-07 00:00:00.000 23
2016-06-08 00:00:00.000 3
2016-06-09 00:00:00.000 23
2016-06-10 00:00:00.000 0
2016-06-17 00:00:00.000 13
2016-06-18 00:00:00.000 23
2016-06-19 00:00:00.000 0
2016-06-20 00:00:00.000 14
2016-06-21 00:00:00.000 23
2016-06-22 00:00:00.000 16
更新:因此,使用经过修改的旋钮式方法(在某些日子里翻了一番),我现在有了这个方法,它确实填补了我的空白,并且可以工作一个月。 一旦我通过将month(obsDate)IN(6)更改为month(obsDate)IN(6,7)来要求两个月的价值,如果它们恰好在第6和第7个月发生冲突,它就会跳过几天。
SELECT CAST(obsDate AS DATE) as obsDate,
(CASE
WHEN COUNT(id) > 12 THEN COUNT(id)
ELSE 0
END) numOfHoursAtHigh
FROM diseaseScores
WHERE diseaseID=2
AND siteID=72160
AND numOfRotationYears=3
AND currentScore > 16
AND month(obsDate) IN (6)
GROUP BY CAST(obsDate AS DATE)
UNION
SELECT CAST(obsDate AS DATE) AS obsDate,
0 AS numOfHoursAtHigh
FROM diseaseScores
WHERE diseaseID=2
AND siteID=72160
AND numOfRotationYears=3
AND currentScore <= 17
AND month(obsDate) IN (6)
and day(obsDate) NOT IN --<-- added from here
(
SELECT distinct day(obsDate)
FROM diseaseScores
WHERE diseaseID=2
AND siteID=72160
AND numOfRotationYears=3
AND currentScore > 16
AND month(obsDate) IN (6)
) --<-- to here to omit the duplicates
GROUP BY CAST(obsDate AS DATE)
ORDER BY CAST(obsDate AS DATE)
围绕预期结果回答问题。 每个月(或几个月)每天的一个记录。 日期,然后是numOfHoursAtHigh的整数,例如
2016-06-01 0
2016-06-02 0
2016-06-03 0
2016-06-04 0
2016-06-05 23
2016-06-06 23
2016-06-07 23
2016-06-08 23
2016-06-09 23
2016-06-10 0
2016-06-11 0
2016-06-12 0
2016-06-13 0
2016-06-14 0
2016-06-15 0
2016-06-16 0
2016-06-17 13
2016-06-18 23
2016-06-19 0
2016-06-20 14
2016-06-21 23
2016-06-22 16
2016-06-23 0
2016-06-24 0
2016-06-25 0
2016-06-26 0
2016-06-27 0
2016-06-28 0
2016-06-29 0
2016-06-30 0
你可以创建另一个SELECT
就是将原来一样,修改的部分WHERE
被过滤掉你想要的结果(第currentScore > 16
),然后UNION
在一起。
SELECT CAST(obsDate AS DATE) as obsDate,
(CASE
WHEN COUNT(id) > 12 THEN COUNT(id)
ELSE 0
END) numOfHoursAtHigh
FROM diseaseScores
WHERE diseaseID=2
AND siteID=72160
AND numOfRotationYears=3
AND currentScore > 16
AND month(obsDate) IN (6)
GROUP BY CAST(obsDate AS DATE)
UNION
SELECT CAST(obsDate AS DATE) AS obsDate,
0 AS numOfHoursAtHigh
FROM diseaseScores
WHERE diseaseID=2
AND siteID=72160
AND numOfRotationYears=3
AND currentScore < 17 --<-- note the change
AND month(obsDate) IN (6)
GROUP BY CAST(obsDate AS DATE)
ORDER BY CAST(obsDate AS DATE)
你好
您可以进行以下查询,
SELECT DS.dateadd(DAY,0, datediff(day,0, obsDate)) as obsDate,
CASE
WHEN DS1.COUNT(id) > 12 THEN COUNT(id)
ELSE 0
END AS numOfHoursAtHigh
FROM diseaseScores DS
INNER JOIN (
SELECT dateadd(DAY,0, datediff(day,0, obsDate)) AS date, COUNT(id)
FROM diseaseScores GROUP BY date
) DS1
ON DS.date = DS1.obsDate
AND DS.diseaseID=2
AND DS.siteID=721DS.60
AND DS.numOfRotationYears=3
AND DS.currentScore > 16
AND DS.month(obsDate) IN (6)
ORDER BY DS.obsDate;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.