如果没有日期记录,MySQL查询显示0

时间:2016-06-25 10:46:38

标签: mysql

我的数据库中有预订表, 参赛作品将逐日插入。

使用我想要生成图表的所有数据。

首先检查我的查询

SELECT
    COUNT(b.id) as total_booking,
    DATE_FORMAT(
        b.appointment_time,
        "%d-%b-%Y"
    ) AS booking_date
FROM
    bookings AS b
GROUP BY
    b.appointment_time

我得到这样的结果。

Total Booking         Booking_date
-----------------------------------------------
 1                     07-Jun-2016
 1                     08-Jun-2016
 2                     09-Jun-2016
 1                     12-Jun-2016
 1                     13-Jun-2016
 1                     15-Jun-2016
 1                     16-Jun-2016
 1                     22-Jun-2016
 1                     25-Jun-2016

我想要它。我想用零填补这些日期差距。 就像我没有预订的日期一样,它应显示为0。

想要这样的输出。

Total 
Booking   Booking_date

0        01-Jun-2016
0        02-Jun-2016
0        03-Jun-2016
0        03-Jun-2016
0        04-Jun-2016
0        05-Jun-2016
0        06-Jun-2016
1        07-Jun-2016
1        08-Jun-2016
0        09-Jun-2016
0        10-Jun-2016
0        11-Jun-2016
1        12-Jun-2016
1        13-Jun-2016
0        14-Jun-2016
1        15-Jun-2016
1        16-Jun-2016
0        17-Jun-2016
0        18-Jun-2016
0        19-Jun-2016
0        20-Jun-2016
0        21-Jun-2016
1        22-Jun-2016
0        23-Jun-2016
0        24-Jun-2016
1        25-Jun-2016
0        26-Jun-2016
0        27-Jun-2016
0        28-Jun-2016
0        29-Jun-2016
0        30-Jun-2016

任何提示? ?

2 个答案:

答案 0 :(得分:0)

这是一个如何做到这一点的例子。这个演示找出你的表的最小和最大日期,并计算之间的天数。它只能工作999天,但你可以扩展它

SELECT
  COUNT(b.id) AS total_booking
  , DATE_FORMAT(
        md,
        "%d-%b-%Y"
    ) AS booking_date
FROM (
  SELECT (SELECT min(appointment_time) FROM bookings) + INTERVAL t.x DAY AS md
  FROM 
  (
      SELECT t*100+h*10+th AS x FROM
      (SELECT 0 th UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
      SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) A,
      (SELECT 0 h UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
      SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) B,
      (SELECT 0 t UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
      SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) C
    ORDER BY x
  ) t
  WHERE x <= (
    SELECT DATEDIFF(max(appointment_time),min(appointment_time)) AS cnt_days FROM bookings
  ) 
) AS date_range
LEFT JOIN bookings b ON date_range.md = b.appointment_time
GROUP BY
    date_range.md;

<强>样品

我的表

MariaDB [yourSchema]> select * from bookings;
+----+------------------+
| id | appointment_time |
+----+------------------+
|  1 | 2016-01-01       |
|  1 | 2016-01-02       |
|  1 | 2016-01-02       |
|  1 | 2016-01-09       |
+----+------------------+
4 rows in set (0.00 sec)

执行查询

MariaDB [yourSchema]> SELECT
    ->   COUNT(b.id) AS total_booking
    ->   , DATE_FORMAT(
    ->         md,
    ->         "%d-%b-%Y"
    ->     ) AS booking_date
    -> FROM (
    ->   SELECT (SELECT min(appointment_time) FROM bookings) + INTERVAL t.x DAY AS md
    ->   FROM
    ->   (
    ->       SELECT t*100+h*10+th AS x FROM
    ->       (SELECT 0 th UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
    ->       SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) A,
    ->       (SELECT 0 h UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
    ->       SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) B,
    ->       (SELECT 0 t UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
    ->       SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) C
    ->     ORDER BY x
    ->   ) t
    ->   WHERE x <= (
    ->     SELECT DATEDIFF(max(appointment_time),min(appointment_time)) AS cnt_days FROM bookings
    ->   )
    -> ) AS date_range
    -> LEFT JOIN bookings b ON date_range.md = b.appointment_time
    -> GROUP BY
    ->     date_range.md;
+---------------+--------------+
| total_booking | booking_date |
+---------------+--------------+
|             1 | 01-Jan-2016  |
|             2 | 02-Jan-2016  |
|             0 | 03-Jan-2016  |
|             0 | 04-Jan-2016  |
|             0 | 05-Jan-2016  |
|             0 | 06-Jan-2016  |
|             0 | 07-Jan-2016  |
|             0 | 08-Jan-2016  |
|             1 | 09-Jan-2016  |
+---------------+--------------+
9 rows in set (0.00 sec)

MariaDB [yourSchema]>

答案 1 :(得分:0)

为您想要的日期范围创建DIM DATE表

CREATE  TABLE IF NOT EXISTS `DIM_DATE` (   `DATE_KEY` INT(11) NOT NULL AUTO_INCREMENT,   `DATE_VALUE` DATE NULL ,   PRIMARY KEY (`DATE_KEY`)  )ENGINE = InnoDB DEFAULT CHARACTER SET = utf8;

如果sp将加载该日期范围的日期

DELIMITER $$ 

CREATE PROCEDURE sp_Load_DIM_DATE(p_start_date DATE, p_end_date DATE)
BEGIN
    DECLARE v_full_date DATE;
    DECLARE v_end_date DATE;
    SET v_full_date = p_start_date;
    SET v_end_date = p_end_date;
    WHILE v_full_date < v_end_date DO

        INSERT INTO DIM_DATE ( DATE_VALUE) VALUES (v_full_date);

        SET v_full_date = DATE_ADD(v_full_date, INTERVAL 1 DAY);
    END WHILE;
END $$

DELIMITER ;

然后使用开始日期和结束日期加载日期范围

CALL  sp_Load_DIM_DATE('2016-05-01',DATE(now()));

SELECT * FROM DIM_DATE;
+----------+------------+
| DATE_KEY | DATE_VALUE |
+----------+------------+
|        1 | 2016-05-01 |
|        2 | 2016-05-02 |
|        3 | 2016-05-03 |
|        4 | 2016-05-04 |
|        5 | 2016-05-05 |
|        6 | 2016-05-06 |
|        7 | 2016-05-07 |
|        8 | 2016-05-08 |
|        9 | 2016-05-09 |
|       10 | 2016-05-10 |
|       11 | 2016-05-11 |
|       12 | 2016-05-12 |
|       13 | 2016-05-13 |
|       14 | 2016-05-14 |
------------------------
-------------------------

|       52 | 2016-06-21 |
|       53 | 2016-06-22 |
|       54 | 2016-06-23 |
|       55 | 2016-06-24 |

然后您可以使用日期值的DIM_DATE LEFT JOIN预订表

来获取它