[英]SQL query count occurrences then group by day but also fill missing days
I have a table called diseaseScores
which has calculation results. 我有一个名为
diseaseScores
的表,该表具有计算结果。 Each hour a running score is calculated ( currentScore
). 每小时计算一次跑步成绩(
currentScore
)。 The objective of this query is to group the hourly scores by the day ( obsDate
), then count the numberOfhours
where the running score is at a level considered high. 该查询的目的是按小时(
obsDate
)将小时分数obsDate
,然后计算跑步分数处于较高水平的numberOfhours
。 High is greater than 16 ( currentScore > 16
). 高大于16(
currentScore > 16
)。
My query so far is: 到目前为止,我的查询是:
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));
The query returns results for 13 days of the month. 该查询返回每月13天的结果。 I wish to fill the gaps so I a have a record for each of the day of the month.
我希望填补空白,所以我每个月的每一天都有一个记录。 The gaps need to have a
numOfHoursAtHigh
result of 0. 间隙需要将
numOfHoursAtHigh
结果numOfHoursAtHigh
0。
How can I do this? 我怎样才能做到这一点? This is for SQL Server 2008 +
这是针对SQL Server 2008 +
The result set being returned is: 返回的结果集为:
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
UPDATE : So using a modified version of knobcreekmans approach (was doubling up certain days) I now have this which does fill my gaps and works great for one month. 更新:因此,使用经过修改的旋钮式方法(在某些日子里翻了一番),我现在有了这个方法,它确实填补了我的空白,并且可以工作一个月。 As soon as I ask for two months worth by changing month(obsDate) IN (6) to month(obsDate) IN (6,7) it skips days if they happen to clash in month 6 and 7. Grrrrrr, am so close!
一旦我通过将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)
To answer to the question around the expected result. 围绕预期结果回答问题。 Its one record for each day of the month (or months) giving to columns.
每个月(或几个月)每天的一个记录。 A date and then an integer for numOfHoursAtHigh eg
日期,然后是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
You could create another SELECT
that is the same as the original, modify the part of your WHERE
clause that is filtering out the results you want ( currentScore > 16
), and then UNION
them together. 你可以创建另一个
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)
Hi, 你好
You can have the below query, 您可以进行以下查询,
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.