MySQL报告--填写空日期

MySQL报告--填写空日期,mysql,sql,Mysql,Sql,我正在构建一个查询以返回每日销售数据。我的当前查询返回一个类似以下内容的表: ---------------------------------- | DATE | SKU | TOTAL | ---------------------------------- | 2014-11-01 | AV155_A | 209.00 | | 2014-11-02 | AV155_B | 627.00 | | 2014-11-04 | AV155_C | 279.00 |

我正在构建一个查询以返回每日销售数据。我的当前查询返回一个类似以下内容的表:

----------------------------------
| DATE       | SKU      | TOTAL  | 
----------------------------------
| 2014-11-01 | AV155_A  | 209.00 |
| 2014-11-02 | AV155_B  | 627.00 |
| 2014-11-04 | AV155_C  | 279.00 |
| 2014-11-05 | AV155    | 279.00 |
| 2014-11-08 | AV1556_A | 209.00 |
| 2014-11-09 | AV1556_B | 627.00 |
| 2014-11-10 | AV1556_C | 279.00 |
| 2014-11-12 | AV1556   | 279.00 |
我想要的是每天显示的结果表,即使没有特定日期的数据点。大概是这样的:

----------------------------------
| DATE       | SKU      | TOTAL  | 
----------------------------------
| 2014-11-01 | AV155_A  | 209.00 |
| 2014-11-02 | AV155_B  | 627.00 |
| 2014-11-03 |          |      0 |
| 2014-11-04 | AV155_C  | 279.00 |
| 2014-11-05 | AV155    | 279.00 |
| 2014-11-06 |          |      0 |
| 2014-11-07 |          |      0 |
| 2014-11-08 | AV1556_A | 209.00 |
| 2014-11-09 | AV1556_B | 627.00 |
| 2014-11-10 | AV1556_C | 279.00 |
| 2014-11-11 |          |      0 |
| 2014-11-12 | AV1556   | 279.00 |
select
  DATE_FORMAT(created_on, '%m-%d-%Y') as date,
  sku,
  SUM(price) as total 
FROM order_items
WHERE created_on between FROM_UNIXTIME(1415577600) AND NOW()
GROUP BY MONTH(created_on), DAY(v.created_on), order_item_sku;
DROP VIEW IF EXISTS seq_0_to_999;
CREATE VIEW seq_0_to_999 AS (
SELECT (a.seq + 10 * (b.seq + 10 * c.seq)) AS seq
  FROM seq_0_to_9 a
  JOIN seq_0_to_9 b
  JOIN seq_0_to_9 c
);
我当前的查询如下所示:

----------------------------------
| DATE       | SKU      | TOTAL  | 
----------------------------------
| 2014-11-01 | AV155_A  | 209.00 |
| 2014-11-02 | AV155_B  | 627.00 |
| 2014-11-03 |          |      0 |
| 2014-11-04 | AV155_C  | 279.00 |
| 2014-11-05 | AV155    | 279.00 |
| 2014-11-06 |          |      0 |
| 2014-11-07 |          |      0 |
| 2014-11-08 | AV1556_A | 209.00 |
| 2014-11-09 | AV1556_B | 627.00 |
| 2014-11-10 | AV1556_C | 279.00 |
| 2014-11-11 |          |      0 |
| 2014-11-12 | AV1556   | 279.00 |
select
  DATE_FORMAT(created_on, '%m-%d-%Y') as date,
  sku,
  SUM(price) as total 
FROM order_items
WHERE created_on between FROM_UNIXTIME(1415577600) AND NOW()
GROUP BY MONTH(created_on), DAY(v.created_on), order_item_sku;
DROP VIEW IF EXISTS seq_0_to_999;
CREATE VIEW seq_0_to_999 AS (
SELECT (a.seq + 10 * (b.seq + 10 * c.seq)) AS seq
  FROM seq_0_to_9 a
  JOIN seq_0_to_9 b
  JOIN seq_0_to_9 c
);

您需要使用外部联接。最简单的方法是,如果您有一个日历表,但您可以随时制作一个:

select c.thedate, oi.sku, sum(price) as total
from (select date('2014-11-01') as thedate union all
             date('2014-11-02') as thedate union all
             date('2014-11-03') as thedate union all
             date('2014-11-04') as thedate union all
             date('2014-11-05') as thedate union all
             date('2014-11-06') as thedate union all
             date('2014-11-07') as thedate union all
             date('2014-11-08') as thedate union all
             date('2014-11-09') as thedate union all
             date('2014-11-10') as thedate union all
             date('2014-11-11') as thedate union all
             date('2014-11-12') as thedate
      ) c left join
      order_items oi
      on c.thedate = date(oi.created_on)
where oi.created_on between FROM_UNIXTIME(1415577600) AND NOW()
group by ci.thedate, oi.sku

您需要使用外部联接。最简单的方法是,如果您有一个日历表,但您可以随时制作一个:

select c.thedate, oi.sku, sum(price) as total
from (select date('2014-11-01') as thedate union all
             date('2014-11-02') as thedate union all
             date('2014-11-03') as thedate union all
             date('2014-11-04') as thedate union all
             date('2014-11-05') as thedate union all
             date('2014-11-06') as thedate union all
             date('2014-11-07') as thedate union all
             date('2014-11-08') as thedate union all
             date('2014-11-09') as thedate union all
             date('2014-11-10') as thedate union all
             date('2014-11-11') as thedate union all
             date('2014-11-12') as thedate
      ) c left join
      order_items oi
      on c.thedate = date(oi.created_on)
where oi.created_on between FROM_UNIXTIME(1415577600) AND NOW()
group by ci.thedate, oi.sku

您需要使用外部联接。最简单的方法是,如果您有一个日历表,但您可以随时制作一个:

select c.thedate, oi.sku, sum(price) as total
from (select date('2014-11-01') as thedate union all
             date('2014-11-02') as thedate union all
             date('2014-11-03') as thedate union all
             date('2014-11-04') as thedate union all
             date('2014-11-05') as thedate union all
             date('2014-11-06') as thedate union all
             date('2014-11-07') as thedate union all
             date('2014-11-08') as thedate union all
             date('2014-11-09') as thedate union all
             date('2014-11-10') as thedate union all
             date('2014-11-11') as thedate union all
             date('2014-11-12') as thedate
      ) c left join
      order_items oi
      on c.thedate = date(oi.created_on)
where oi.created_on between FROM_UNIXTIME(1415577600) AND NOW()
group by ci.thedate, oi.sku

您需要使用外部联接。最简单的方法是,如果您有一个日历表,但您可以随时制作一个:

select c.thedate, oi.sku, sum(price) as total
from (select date('2014-11-01') as thedate union all
             date('2014-11-02') as thedate union all
             date('2014-11-03') as thedate union all
             date('2014-11-04') as thedate union all
             date('2014-11-05') as thedate union all
             date('2014-11-06') as thedate union all
             date('2014-11-07') as thedate union all
             date('2014-11-08') as thedate union all
             date('2014-11-09') as thedate union all
             date('2014-11-10') as thedate union all
             date('2014-11-11') as thedate union all
             date('2014-11-12') as thedate
      ) c left join
      order_items oi
      on c.thedate = date(oi.created_on)
where oi.created_on between FROM_UNIXTIME(1415577600) AND NOW()
group by ci.thedate, oi.sku

这里有一个答案,解决了灵活的日期列表的需要。您需要找到一种方法来获取一个包含适当范围内所有日期的虚拟表,然后将它们连接到摘要中。下面是一个查询,它将获取范围内的日期

SELECT mintime + INTERVAL seq.seq DAY AS reportdate
  FROM (
        SELECT MIN(DATE(created_on)) AS mintime,
               MAX(DATE(created_on)) AS maxtime
          FROM order_items
         WHERE created_on >= starting_time
           AND created_on <= NOW()
       ) AS order_items
  JOIN seq_0_to_999 AS seq 
                    ON seq.seq < TIMESTAMPDIFF(DAY,mintime,maxtime)
这看起来像一个令人讨厌的大问题。但是如果你把它看作是由不同层次的查询组成的三明治,它其实并不复杂

它使用
LEFT JOIN
,因此即使
order\u items
表中没有相应的数据,它也会确保保留范围内的所有日期

最后,这个
seq_0_至_999
表怎么样?从哪里得到以零开始的整数?答案是:我们必须安排这样做;这些数字不是MySQL内置的。(它们内置在名为MariaDB的MySQL fork中)创建一个包含0-9之间整数的短表,如下所示:

DROP TABLE IF EXISTS seq_0_to_9;
CREATE TABLE seq_0_to_9 AS
   SELECT 0 AS seq 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;
然后创建一个视图,将该表与其自身连接起来,以生成1000个组合,如下所示:

----------------------------------
| DATE       | SKU      | TOTAL  | 
----------------------------------
| 2014-11-01 | AV155_A  | 209.00 |
| 2014-11-02 | AV155_B  | 627.00 |
| 2014-11-03 |          |      0 |
| 2014-11-04 | AV155_C  | 279.00 |
| 2014-11-05 | AV155    | 279.00 |
| 2014-11-06 |          |      0 |
| 2014-11-07 |          |      0 |
| 2014-11-08 | AV1556_A | 209.00 |
| 2014-11-09 | AV1556_B | 627.00 |
| 2014-11-10 | AV1556_C | 279.00 |
| 2014-11-11 |          |      0 |
| 2014-11-12 | AV1556   | 279.00 |
select
  DATE_FORMAT(created_on, '%m-%d-%Y') as date,
  sku,
  SUM(price) as total 
FROM order_items
WHERE created_on between FROM_UNIXTIME(1415577600) AND NOW()
GROUP BY MONTH(created_on), DAY(v.created_on), order_item_sku;
DROP VIEW IF EXISTS seq_0_to_999;
CREATE VIEW seq_0_to_999 AS (
SELECT (a.seq + 10 * (b.seq + 10 * c.seq)) AS seq
  FROM seq_0_to_9 a
  JOIN seq_0_to_9 b
  JOIN seq_0_to_9 c
);

我在

上详细地写了这篇文章。这里有一个答案,可以满足灵活的日期列表的需要。您需要找到一种方法来获取一个包含适当范围内所有日期的虚拟表,然后将它们连接到摘要中。下面是一个查询,它将获取范围内的日期

SELECT mintime + INTERVAL seq.seq DAY AS reportdate
  FROM (
        SELECT MIN(DATE(created_on)) AS mintime,
               MAX(DATE(created_on)) AS maxtime
          FROM order_items
         WHERE created_on >= starting_time
           AND created_on <= NOW()
       ) AS order_items
  JOIN seq_0_to_999 AS seq 
                    ON seq.seq < TIMESTAMPDIFF(DAY,mintime,maxtime)
这看起来像一个令人讨厌的大问题。但是如果你把它看作是由不同层次的查询组成的三明治,它其实并不复杂

它使用
LEFT JOIN
,因此即使
order\u items
表中没有相应的数据,它也会确保保留范围内的所有日期

最后,这个
seq_0_至_999
表怎么样?从哪里得到以零开始的整数?答案是:我们必须安排这样做;这些数字不是MySQL内置的。(它们内置在名为MariaDB的MySQL fork中)创建一个包含0-9之间整数的短表,如下所示:

DROP TABLE IF EXISTS seq_0_to_9;
CREATE TABLE seq_0_to_9 AS
   SELECT 0 AS seq 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;
然后创建一个视图,将该表与其自身连接起来,以生成1000个组合,如下所示:

----------------------------------
| DATE       | SKU      | TOTAL  | 
----------------------------------
| 2014-11-01 | AV155_A  | 209.00 |
| 2014-11-02 | AV155_B  | 627.00 |
| 2014-11-03 |          |      0 |
| 2014-11-04 | AV155_C  | 279.00 |
| 2014-11-05 | AV155    | 279.00 |
| 2014-11-06 |          |      0 |
| 2014-11-07 |          |      0 |
| 2014-11-08 | AV1556_A | 209.00 |
| 2014-11-09 | AV1556_B | 627.00 |
| 2014-11-10 | AV1556_C | 279.00 |
| 2014-11-11 |          |      0 |
| 2014-11-12 | AV1556   | 279.00 |
select
  DATE_FORMAT(created_on, '%m-%d-%Y') as date,
  sku,
  SUM(price) as total 
FROM order_items
WHERE created_on between FROM_UNIXTIME(1415577600) AND NOW()
GROUP BY MONTH(created_on), DAY(v.created_on), order_item_sku;
DROP VIEW IF EXISTS seq_0_to_999;
CREATE VIEW seq_0_to_999 AS (
SELECT (a.seq + 10 * (b.seq + 10 * c.seq)) AS seq
  FROM seq_0_to_9 a
  JOIN seq_0_to_9 b
  JOIN seq_0_to_9 c
);

我在

上详细地写了这篇文章。这里有一个答案,可以满足灵活的日期列表的需要。您需要找到一种方法来获取一个包含适当范围内所有日期的虚拟表,然后将它们连接到摘要中。下面是一个查询,它将获取范围内的日期

SELECT mintime + INTERVAL seq.seq DAY AS reportdate
  FROM (
        SELECT MIN(DATE(created_on)) AS mintime,
               MAX(DATE(created_on)) AS maxtime
          FROM order_items
         WHERE created_on >= starting_time
           AND created_on <= NOW()
       ) AS order_items
  JOIN seq_0_to_999 AS seq 
                    ON seq.seq < TIMESTAMPDIFF(DAY,mintime,maxtime)
这看起来像一个令人讨厌的大问题。但是如果你把它看作是由不同层次的查询组成的三明治,它其实并不复杂

它使用
LEFT JOIN
,因此即使
order\u items
表中没有相应的数据,它也会确保保留范围内的所有日期

最后,这个
seq_0_至_999
表怎么样?从哪里得到以零开始的整数?答案是:我们必须安排这样做;这些数字不是MySQL内置的。(它们内置在名为MariaDB的MySQL fork中)创建一个包含0-9之间整数的短表,如下所示:

DROP TABLE IF EXISTS seq_0_to_9;
CREATE TABLE seq_0_to_9 AS
   SELECT 0 AS seq 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;
然后创建一个视图,将该表与其自身连接起来,以生成1000个组合,如下所示:

----------------------------------
| DATE       | SKU      | TOTAL  | 
----------------------------------
| 2014-11-01 | AV155_A  | 209.00 |
| 2014-11-02 | AV155_B  | 627.00 |
| 2014-11-03 |          |      0 |
| 2014-11-04 | AV155_C  | 279.00 |
| 2014-11-05 | AV155    | 279.00 |
| 2014-11-06 |          |      0 |
| 2014-11-07 |          |      0 |
| 2014-11-08 | AV1556_A | 209.00 |
| 2014-11-09 | AV1556_B | 627.00 |
| 2014-11-10 | AV1556_C | 279.00 |
| 2014-11-11 |          |      0 |
| 2014-11-12 | AV1556   | 279.00 |
select
  DATE_FORMAT(created_on, '%m-%d-%Y') as date,
  sku,
  SUM(price) as total 
FROM order_items
WHERE created_on between FROM_UNIXTIME(1415577600) AND NOW()
GROUP BY MONTH(created_on), DAY(v.created_on), order_item_sku;
DROP VIEW IF EXISTS seq_0_to_999;
CREATE VIEW seq_0_to_999 AS (
SELECT (a.seq + 10 * (b.seq + 10 * c.seq)) AS seq
  FROM seq_0_to_9 a
  JOIN seq_0_to_9 b
  JOIN seq_0_to_9 c
);

我在

上详细地写了这篇文章。这里有一个答案,可以满足灵活的日期列表的需要。您需要找到一种方法来获取一个包含适当范围内所有日期的虚拟表,然后将它们连接到摘要中。下面是一个查询,它将获取范围内的日期

SELECT mintime + INTERVAL seq.seq DAY AS reportdate
  FROM (
        SELECT MIN(DATE(created_on)) AS mintime,
               MAX(DATE(created_on)) AS maxtime
          FROM order_items
         WHERE created_on >= starting_time
           AND created_on <= NOW()
       ) AS order_items
  JOIN seq_0_to_999 AS seq 
                    ON seq.seq < TIMESTAMPDIFF(DAY,mintime,maxtime)
这看起来像一个令人讨厌的大问题。但是如果你把它看作是由不同层次的查询组成的三明治,它其实并不复杂

它使用
LEFT JOIN
,因此即使
order\u items
表中没有相应的数据,它也会确保保留范围内的所有日期

最后,这个
seq_0_至_999
表怎么样?从哪里得到以零开始的整数?答案是:我们必须安排这样做;这些数字不是MySQL内置的。(它们内置在名为MariaDB的MySQL fork中)创建一个包含0-9之间整数的短表,如下所示:

DROP TABLE IF EXISTS seq_0_to_9;
CREATE TABLE seq_0_to_9 AS
   SELECT 0 AS seq 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;
然后创建一个视图,将该表与其自身连接起来,以生成1000个组合,如下所示:

----------------------------------
| DATE       | SKU      | TOTAL  | 
----------------------------------
| 2014-11-01 | AV155_A  | 209.00 |
| 2014-11-02 | AV155_B  | 627.00 |
| 2014-11-03 |          |      0 |
| 2014-11-04 | AV155_C  | 279.00 |
| 2014-11-05 | AV155    | 279.00 |
| 2014-11-06 |          |      0 |
| 2014-11-07 |          |      0 |
| 2014-11-08 | AV1556_A | 209.00 |
| 2014-11-09 | AV1556_B | 627.00 |
| 2014-11-10 | AV1556_C | 279.00 |
| 2014-11-11 |          |      0 |
| 2014-11-12 | AV1556   | 279.00 |
select
  DATE_FORMAT(created_on, '%m-%d-%Y') as date,
  sku,
  SUM(price) as total 
FROM order_items
WHERE created_on between FROM_UNIXTIME(1415577600) AND NOW()
GROUP BY MONTH(created_on), DAY(v.created_on), order_item_sku;
DROP VIEW IF EXISTS seq_0_to_999;
CREATE VIEW seq_0_to_999 AS (
SELECT (a.seq + 10 * (b.seq + 10 * c.seq)) AS seq
  FROM seq_0_to_9 a
  JOIN seq_0_to_9 b
  JOIN seq_0_to_9 c
);

我在

上详细地写了这篇文章,我相信要做到这一点,您要么需要执行更新以插入所需范围内没有数据的日期行,要么使用SQL的流控制和编程,即创建一个在日期范围内循环的存储过程。不知道如何在一个简单的SELECT查询中实现这一点……我认为,要做到这一点,您要么需要执行更新,为所需范围内没有数据的日期插入行,要么使用SQL的流控制和编程,即创建一个在日期范围内循环的存储过程。不知道如何在一个简单的SELECT查询中实现这一点……我认为,要做到这一点,您要么需要执行更新,为所需范围内没有数据的日期插入行,要么使用SQL的流控制和编程,即创建一个在日期范围内循环的存储过程。不知道如何在一个简单的