轻松修复MySQL

时间:2016-09-09 12:49:56

标签: mysql

我已经做了这个查询,我计算每小时有多少新插入。问题是我的查询不会显示没有新条目的小时数。

如何以简单的方式解决这个问题?

SELECT
count(HOUR(delivered))as count,
CASE 
    WHEN HOUR(delivered) = 0 THEN '0'
    WHEN HOUR(delivered) = 1 THEN '1'
    WHEN HOUR(delivered) = 2 THEN '2'
    WHEN HOUR(delivered) = 3 THEN '3'
    WHEN HOUR(delivered) = 4 THEN '4'
    WHEN HOUR(delivered) = 5 THEN '5'
    WHEN HOUR(delivered) = 6 THEN '6'
    WHEN HOUR(delivered) = 7 THEN '7'
    WHEN HOUR(delivered) = 8 THEN '8'
    WHEN HOUR(delivered) = 9 THEN '9'
    WHEN HOUR(delivered) = 10 THEN '10'
    WHEN HOUR(delivered) = 11 THEN '11'
    WHEN HOUR(delivered) = 12 THEN '12'
    WHEN HOUR(delivered) = 13 THEN '13'
    WHEN HOUR(delivered) = 14 THEN '14'
    WHEN HOUR(delivered) = 15 THEN '15'
    WHEN HOUR(delivered) = 16 THEN '16'
    WHEN HOUR(delivered) = 17 THEN '17'
    WHEN HOUR(delivered) = 18 THEN '18'
    WHEN HOUR(delivered) = 19 THEN '19'
    WHEN HOUR(delivered) = 20 THEN '20'
    WHEN HOUR(delivered) = 21 THEN '21'
    WHEN HOUR(delivered) = 22 THEN '22'
    WHEN HOUR(delivered) = 23 THEN '23'

END AS intervals
FROM
    Wardrobe_CloakTable
WHERE
    payingcustomerID = 2
    AND DAY(delivered) = 09
    AND MONTH(delivered) = 09
    AND YEAR(delivered) = 2016
GROUP BY intervals

1 个答案:

答案 0 :(得分:1)

您可以从包含0到23之间的值的表开始,然后左键加入数据表。

修改:让我们尝试将COUNT(delivered)更改为SUM(delivered IS NOT NULL),看看我们是否可以在每一行获取数值。

让我们从简化您的查询开始。这将在一瞬间派上用场,因为我们必须使用它来进行更大的查询。

            SELECT SUM(delivered IS NOT NULL) AS count,
                   HOUR(delivered) AS intervals
              FROM Wardrobe_CloakTable
             WHERE payingcustomerID = 2
               AND delivered >= '2016-09-09'
               AND delivered <  '2016-09-09' + INTERVAL 1 DAY
             GROUP BY HOUR(delivered)

(顺便说一句,(payingcustomerID, delivered)上的索引会使此查询非常快。)

现在我们需要一个数字为0 - 23的虚拟表。这样做可以解决这个问题:它使用JOIN组合生成2 x 2 x 2 x 3整数。我们将这个小表seq_0_to_23称为。为什么?因为这些sequence tables内置在MySQL的MariaDB分支中。

          SELECT A.N + 2*(B.N + 2*(C.N +2*(D.N))) AS seq
            FROM (SELECT 0 AS N UNION SELECT 1) AS A
            JOIN (SELECT 0 AS N UNION SELECT 1) AS B
            JOIN (SELECT 0 AS N UNION SELECT 1) AS C
            JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2) AS D

最后,你使用LEFT JOIN,就像这样。

SELECT SUM(delivered IS NOT NULL) AS count,
       seq AS intervals
 FROM (
                SELECT A.N + 2*(B.N + 2*(C.N +2*(D.N))) AS seq
                  FROM (SELECT 0 AS N UNION SELECT 1) AS A
                  JOIN (SELECT 0 AS N UNION SELECT 1) AS B
                  JOIN (SELECT 0 AS N UNION SELECT 1) AS C
                  JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2) AS D
       ) seq_0_to_23
  LEFT JOIN Wardrobe_CloakTable ON HOUR(delivered) = seq
 WHERE payingcustomerID = 2
   AND delivered >= '2016-09-09'
   AND delivered <  '2016-09-09' + INTERVAL 1 DAY
 GROUP BY seq
 ORDER BY seq

这使用序列表作为一天中所有小时的来源,然后从实际数据中提取匹配值。

如果你正在使用MariaDB,这就是这样的。如您所见,内置序列表使查询看起来更加优雅。

SELECT SUM(delivered IS NOT NULL) AS count,
       seq AS intervals
  FROM seq_0_to_23
  LEFT JOIN Wardrobe_CloakTable ON HOUR(delivered) = seq
 WHERE payingcustomerID = 2
   AND delivered >= '2016-09-09'
   AND delivered <  '2016-09-09' + INTERVAL 1 DAY
 GROUP BY seq
 ORDER BY seq

我们正在使用SELECT SUM(delivered IS NOT NULL)因为我们需要每行的聚合函数中的数值结果。 <{1}}返回1或0,因此delivered IS NOT NULL应该可以正常工作。

这里是comprehensive explanation of this technique.