根据日期计算/分组行,包括缺失

时间:2013-09-25 10:57:57

标签: mysql sql

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

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个表的例子,一个有记录,另一个有日期,但我最好还是有一个表。

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

有没有人知道如何做到这一点?

由于

3 个答案:

答案 0 :(得分: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 :(得分:0)

尝试这样的事情!

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

要检索另一列c2中存在特定值的c1值列表,您需要一个IN子句指定c2值和一个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

答案 2 :(得分:0)

使用以下存储过程,它可以让您获得超过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
相关问题