MySql 单表,选择过去 7 天并包含空行

Posted

技术标签:

【中文标题】MySql 单表,选择过去 7 天并包含空行【英文标题】:MySql Single Table, Select last 7 days and include empty rows 【发布时间】:2014-04-25 18:20:22 【问题描述】:

我在 *** 上搜索过类似的问题,但我不明白如何使这项工作,我正在尝试做什么......

所以,我想从数据库中获取最近 7 天的交易并获取总销售额,如果某天没有数据,还包括空行。

到目前为止我所拥有的: http://sqlfiddle.com/#!2/f4eda/6

这个输出:

| PURCHASE_DATE | AMOUNT |
|---------------|--------|
|    2014-04-25 |     19 |
|    2014-04-24 |     38 |
|    2014-04-22 |     19 |
|    2014-04-19 |     19 |

我想要什么:

| PURCHASE_DATE | AMOUNT |
|---------------|--------|
|    2014-04-25 |     19 |
|    2014-04-24 |     38 |
|    2014-04-23 |      0 |
|    2014-04-22 |     19 |
|    2014-04-21 |      0 |
|    2014-04-20 |      0 |
|    2014-04-19 |     19 |

任何帮助表示赞赏:)

【问题讨论】:

mysql: Select all data between two dates的可能重复 【参考方案1】:

这并不容易。我从这个线程 generate days from date range 获得了帮助,并将其与您的查询结合起来。

所以我们的想法是获取过去 7 天的日期列表,然后将这些日期与静态量 0 连接到您的查询中,然后最后将它们相加。这可以用于任何日期范围,只需要在两个查询中更改它们

select 
t1.purchase_date,
coalesce(SUM(t1.amount+t2.amount), 0) AS amount
from
(
  select DATE_FORMAT(a.Date,'%Y-%m-%d') as purchase_date,
  '0' as  amount
  from (
    select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
  ) a
  where a.Date BETWEEN NOW() - INTERVAL 7 DAY AND NOW()
)t1
left join
(
  SELECT DATE_FORMAT(purchase_date, '%Y-%m-%d') as purchase_date,
  coalesce(SUM(amount), 0) AS amount
  FROM transactions
  WHERE purchase_date BETWEEN NOW() - INTERVAL 7 DAY AND NOW()
  AND vendor_id = 0
  GROUP BY purchase_date
)t2
on t2.purchase_date = t1.purchase_date
group by t1.purchase_date
order by t1.purchase_date desc

DEMO

【讨论】:

这应该是公认的答案......非常好。它也是动态的,因此您不必在其中硬编码日期。【参考方案2】:

只需将子查询与您想要的日期放在一起并使用left outer join

select d.thedate, coalesce(SUM(amount), 0) AS amount
from (select date('2014-04-25') as thedate union all
      select date('2014-04-24') union all
      select date('2014-04-23') union all
      select date('2014-04-22') union all
      select date('2014-04-21') union all
      select date('2014-04-20') union all
      select date('2014-04-19')
     ) d left outer join
     transactions t
     on t.purchase_date = d.thedate and vendor_id = 0
GROUP BY d.thedate
ORDER BY d.thedate DESC;

【讨论】:

谢谢,但它给出了一些错误sqlfiddle.com/#!2/f4eda/41 Exception -> string(282) "SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual对应于您的 MySQL 服务器版本,以便在第 3 行的“union all select date('2014-04-23' union all select date'附近使用正确的语法”【参考方案3】:

这是过去 7 天的数据;

select d.thedate, coalesce(SUM(amount), 0) AS amount
from (select DATE(NOW()) as thedate union all
      select DATE(DATE_SUB( NOW(), INTERVAL 1 DAY)) union all
      select DATE(DATE_SUB( NOW(), INTERVAL 2 DAY)) union all
      select DATE(DATE_SUB( NOW(), INTERVAL 3 DAY)) union all
      select DATE(DATE_SUB( NOW(), INTERVAL 4 DAY)) union all
      select DATE(DATE_SUB( NOW(), INTERVAL 5 DAY)) union all
      select DATE(DATE_SUB( NOW(), INTERVAL 6 DAY))) d left outer join
     transactions t
     on t.purchase_date = d.thedate and vendor_id = 0
GROUP BY d.thedate
ORDER BY d.thedate DESC;

【讨论】:

【参考方案4】:
with recursive all_dates(dt) as (
    select '2014-04-19' as dt
    union all 
    select dt + interval 1 day
    from all_dates
    where dt + interval 1 day <= '2014-04-25'
)
select d.dt as purchase_date, coalesce(m.amount, 0) as purchased
from all_dates as d
left join mytable m
on d.dt = m.purchase_date
order by purchase_date desc;

【讨论】:

虽然这可能会回答问题,但您应该 edit 您的回答包括对如何此脚本回答问题的简短说明。这有助于提供上下文,并使答案对以后可能遇到相同问题的人更有用。

以上是关于MySql 单表,选择过去 7 天并包含空行的主要内容,如果未能解决你的问题,请参考以下文章

BufferedReader 没有读取过去的空行 [关闭]

为不存在的数据返回空行

xlrd读取数据时判断空行

MySQL - 是不是可以显示空行? [复制]

Mysql BETWEEN 请求返回空行

SQL - 选择所有不匹配空行的行