【问题标题】:SQL query count occurrences then group by day but also fill missing daysSQL 查询计数出现然后按天分组,但也填充缺失的天数
【发布时间】:2016-09-27 15:34:38
【问题描述】:

我有一个名为diseaseScores 的表,其中包含计算结果。每小时计算一次运行分数 (currentScore)。此查询的目的是按天 (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 结果为 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

更新:因此,使用改进版的knobcreekmans 方法(在某些日子里翻倍)我现在有了这个,它确实填补了我的空白,并且在一个月内效果很好。一旦我通过将月份(obsDate)IN(6)更改为月份(obsDate)IN(6,7)来要求两个月的价值,如果它们碰巧在第6个月和第7个月发生冲突,它就会跳过几天。Grrrrrr,我太近了!

        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

【问题讨论】:

  • 你能显示预期的结果集吗

标签: sql tsql sql-server-2008-r2


【解决方案1】:

您可以创建另一个与原始相同的SELECT,修改WHERE 子句中过滤出您想要的结果的部分(currentScore &gt; 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)

【讨论】:

  • 是的,很好,我喜欢这个。它几乎可以完美运行。由于某种原因,它显示了 2016-06-17 的两条记录。一个在 0 处不正确,一个在 13 处正确。它也在 2016 年 6 月 20 日和 2016 年 6 月 22 日这样做。试图弄清楚为什么 ATM
【解决方案2】:


您好,
您可以进行以下查询,

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;

【讨论】:

  • 嗨,吉姆,感谢您的时间和精力。我正在处理这个查询中的一些问题,看看它是否可以工作
  • 当然。谢谢
猜你喜欢
  • 2010-12-12
  • 2018-06-23
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 2018-07-08
  • 2013-03-19
  • 2014-12-11
  • 2016-07-18
相关资源
最近更新 更多