【问题标题】:Create a by Date and hour breakdown from TIMESTAMP field MYSQL从 TIMESTAMP 字段 MYSQL 创建按日期和小时细分
【发布时间】:2014-12-01 13:01:26
【问题描述】:

我正在尝试创建一个查询,该查询按日期和小时提供ids 的细分,其中空白结果显示为零。

到目前为止,这是 MYSQL 查询:

SELECT DATE(received),
  CONCAT(hourly.hour, ':00 - ', hourly.hour+1, ':00') AS Hours,  
  COALESCE(COUNT(id),0) AS "Leads"
FROM hourly
LEFT JOIN digital_lead ON hourly.hour=hour(digital_lead.received)
WHERE 
  digital_lead.received>=DATE_SUB('2014-11-01', INTERVAL 24 HOUR) AND
  digital_lead.received<=DATE_SUB('2014-11-26', INTERVAL 24 HOUR) 
GROUP BY DATE(received), hourly.hour
ORDER BY DATE(received)

我有一个从 0 到 23 的整数表,组成了 hourly 表。

目前,此查询仅显示结果存在的时间段 - 如下所示:

DATE(received)       Hours  Leads
2014-11-12           11:00 - 12:00  23
2014-11-12           12:00 - 13:00  19
2014-11-12           13:00 - 14:00  18
2014-11-12           14:00 - 15:00  17
2014-11-12           15:00 - 16:00  23
2014-11-12           16:00 - 17:00  13
2014-11-12           17:00 - 18:00  17

查询应该显示来自00:00 - 11:00 的时间段的零结果,而不是在查询结果中遗漏它们。它似乎忽略了COALESCE 函数,我尝试用IFNULL(COUNT(id), 0) 替换它,没有区别。

我已经尝试了这个问题/答案中的解决方案 - STACKOVERFLOW LINK

但是,这对我不起作用。

有什么建议吗?

编辑

这里是 SQL FIDDLE 了解更多详情

【问题讨论】:

  • 左连接与 where 使其成为内连接。您可以移动 where 条件作为加入条件。
  • @AbhikChakraborty - 你能举个例子吗?谢谢
  • LEFT JOIN digital_lead ON hourly.hour=hour(digital_lead.received) and digital_lead.received&gt;=DATE_SUB('2014-11-01', INTERVAL 24 HOUR) and digital_lead.received&lt;=DATE_SUB('2014-11-26', INTERVAL 24 HOUR) 也删除了where 子句
  • @AbhikChakraborty - 删除 WHERE 子句并替换为您建议的语句会产生相同的结果。还有什么建议吗?
  • hmm 你能用一些示例数据创建一个 sqlfiddle 以便我们看看吗?

标签: mysql timestamp


【解决方案1】:

好的,这需要一些时间。这是我能想到的最好的办法。可能有更好的方法来做到这一点,但加入时缺少日期或时间总是很复杂。我已经给出了与缺少日期相关的few answers,但这是完全不同的。

因此,我使用相同的想法在查询中进行了一些更改以检索数据,如下所示

select
t1.date_received,
t1.Hours,
COALESCE(t2.`Leads`,0) as `Leads`
from
(
  select
  distinct DATE(received) as date_received,
  concat (DATE(received),'-',h.hour) as date_hour,
  CONCAT(h.hour, ':00 - ', h.hour+1, ':00') AS Hours 
  from digital_lead
  cross join (select hour from hourly)h
)t1
left join
(
  SELECT DATE(received) as date_received,
  concat (DATE(received),'-',hour) as date_hour,
  CONCAT(hourly.hour, ':00 - ', hourly.hour+1, ':00') AS Hours,  
  COALESCE(COUNT(id),0) AS "Leads"
  FROM hourly
  LEFT JOIN digital_lead ON hourly.hour=hour(digital_lead.received)
  and digital_lead.received>=DATE_SUB('2014-11-01', INTERVAL 24 HOUR)
  and digital_lead.received<=DATE_SUB('2014-11-26', INTERVAL 24 HOUR) 
  GROUP BY DATE(received), hourly.hour
)t2
on t1.date_hour = t2.date_hour
order by t1.date_received,
cast(substring_index(t1.Hours,':',1) as unsigned)

FIDDLE

【讨论】:

  • 这非常复杂 - 需要一些时间来消化。非常感谢您对这个问题的帮助。谢谢。
  • 是的,它有点复杂,但没有那么多。这个想法是首先获取不同的日期,然后通过连接日期和小时来交叉加入小时。然后使用您当前的查询并对其进行左移,以便显示左表中的所有日期-小时和计数。
  • 我刚刚注意到没有任何数据的日期不会出现在结果中,例如,2014-11-01 - 2014-11-11 之间的日期不会显示在结果中。是否可以在没有任何数据的情况下显示零?也许加入已经生成日期范围的日历表?
  • 是的,这可以做到,但会使其更复杂,现在我们需要根据范围生成动态日期。这里是sqlfiddle.com/#!2/715cee7/30
  • 再次感谢!我对你的回答做了一些小改动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
  • 2015-01-22
  • 1970-01-01
  • 2016-09-13
相关资源
最近更新 更多