【问题标题】:Count/group rows based on date including missing根据日期计算/分组行,包括缺失
【发布时间】:2013-09-25 10:57:56
【问题描述】:

我的数据库中有一堆表示订单的行,即

id | date
---------------------
1  | 2013-09-01
2  | 2013-09-01
3  | 2013-09-02
4  | 2013-09-04
5  | 2013-09-04

我想要显示每天的行数,包括缺失的天数,所以输出是:

2013-09-01 | 2
2013-09-02 | 1
2013-09-03 | 0
2013-09-04 | 2

我已经看到有 2 个表的示例,一个带有记录,另一个带有日期,但理想情况下我希望有一个单独的表。

我目前可以找到有记录的行,但找不到没有记录的日期。

有人知道怎么做吗?

谢谢

【问题讨论】:

  • 如果您的日期范围不受某种限制,唯一好的选择是拥有两个表(一个带日期),因为 MySQL 不支持序列。
  • 限制显示最近7天的订单。

标签: mysql sql


【解决方案1】:

如果要获取最近 7 天的数据,可以通过UNION 生成伪表,例如:

SELECT 
  COUNT(t.id), 
  fixed_days.fixed_date 
FROM t 
  RIGHT JOIN 
  (SELECT CURDATE() as fixed_date 
   UNION ALL SELECT CURDATE() - INTERVAL 1 day 
   UNION ALL SELECT CURDATE() - INTERVAL 2 day 
   UNION ALL SELECT CURDATE() - INTERVAL 3 day 
   UNION ALL SELECT CURDATE() - INTERVAL 4 day 
   UNION ALL SELECT CURDATE() - INTERVAL 5 day 
   UNION ALL SELECT CURDATE() - INTERVAL 6 day) AS fixed_days 
  ON t.`date` = `fixed_days`.`fixed_date`
GROUP BY 
  `fixed_days`.`fixed_date`

-看到这个fiddle demo。请注意,如果您的字段是 DATETIME 日期类型,那么您需要先申请 DATE()

SELECT 
  COUNT(t.id), 
  fixed_days.fixed_date 
FROM t 
  RIGHT JOIN 
  (SELECT CURDATE() as fixed_date 
   UNION ALL SELECT CURDATE() - INTERVAL 1 day 
   UNION ALL SELECT CURDATE() - INTERVAL 2 day 
   UNION ALL SELECT CURDATE() - INTERVAL 3 day 
   UNION ALL SELECT CURDATE() - INTERVAL 4 day 
   UNION ALL SELECT CURDATE() - INTERVAL 5 day 
   UNION ALL SELECT CURDATE() - INTERVAL 6 day) AS fixed_days 
  ON DATE(t.`date`) = `fixed_days`.`fixed_date`
GROUP BY 
  `fixed_days`.`fixed_date`

【讨论】:

  • 无论日期范围内是否没有行,都会为每一行返回1
  • 如果字段是datetime 怎么办?更改 SQL 容易吗?
【解决方案2】:

试试这样的东西!

SELECT 
  c1,  
  GROUP_CONCAT(c2 ORDER BY c2) AS 'C2 values' 
FROM table 
GROUP BY c1; 

要检索在另一列 c2 中存在特定值的 c1 值列表,您需要一个指定 c2 值的 IN 子句和一个指定列表中不同项目所需数量的 HAVING 子句。 .

SELECT c1  
FROM table 
WHERE c2 IN (1,2,3,4) 
GROUP BY c1 
HAVING COUNT(DISTINCT c2)=4; 

有关此相关问题的更多帮助

Counting all rows with specific columns and grouping by week

【讨论】:

    【解决方案3】:

    使用下面的存储过程可以让你得到超过7天的结果,只要传递你想要的天数

    DELIMITER $$
    
    CREATE DEFINER=`server`@`%` PROCEDURE `test`(d INT)
    BEGIN
    
        CREATE TEMPORARY TABLE dates 
        (
          f_day DATETIME
        );
    
        WHILE d > 0 DO
            INSERT INTO dates SELECT DATE(NOW())-d;
            SET d = d - 1;
        END WHILE;
    
        SELECT 
            IF(isnull(`id`),0,`id`), 
            `fixed_days`.`f_day`
        FROM t 
        RIGHT JOIN 
            dates AS `fixed_days` 
            ON t.`date` = `fixed_days`.`f_day`
        GROUP BY 
        `fixed_days`.`f_day`;
    
        DROP TABLE dates;
    END
    

    【讨论】:

      猜你喜欢
      • 2020-12-04
      • 2014-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      相关资源
      最近更新 更多