在postgres / COALESCE中正确使用COALESCE无法正常工作

时间:2014-07-09 10:23:47

标签: postgresql coalesce

我正在尝试返回每小时执行搜索次数的报告。我的结果不包括零搜索的小时数,我认为我的COALESCE语法正确。谁能看到我做错了什么?感谢

SELECT CAST(startdatetime as Date),extract(hour from startdatetime) as hr, COALESCE(count(distinct id),0) as average_per_hour
FROM search WHERE CAST(startdatetime As Date) = '2014/07/05' 
GROUP BY CAST(startdatetime as Date),extract(hour from startdatetime) 
ORDER BY CAST(startdatetime as Date),extract(hour from startdatetime)

enter image description here

2 个答案:

答案 0 :(得分:2)

你需要的是一个"查找"一天中所有时间的桌子。然后针对搜索表进行左连接。由于所有可能行的左连接,您可以包含"缺少"小时数。

如下所示(未经测试,可能存在语法错误!

with hours as (
  select hr
  from generate_series(0,23) hr
)
SELECT CAST(search.startdatetime as Date), 
       hours.hr, 
       count(distinct search.id) as average_per_hour
FROM hours 
  left join search on extract(hour from search.startdatetime) = hours.hr
WHERE cast(startdatetime As Date) = date '2014-07-05' 
GROUP BY cast(startdatetime as Date),extract(hour from startdatetime) 
ORDER BY CAST(startdatetime as Date),extract(hour from startdatetime);

如图所示,只有选择一天时才会有效。

答案 1 :(得分:2)

一些改进,但与@ a_horse_with_no_name的答案基本相同:

SELECT DATE '2014-07-05', hr, COUNT(DISTINCT id) AS average_per_hour
FROM generate_series(0, 23) hr
LEFT JOIN search ON EXTRACT(HOUR FROM startdatetime) = hr AND CAST(startdatetime AS DATE) = '2014-07-05' 
GROUP BY hr
ORDER BY hr

CAST(startdatetime AS DATE)&中使用ORDER BY GROUP BY无关紧要,因为您只搜索了一天。如果情况并非如此,您还需要调整generate_series()

修改

这可以在多天内使用:

SELECT CAST(hr AS DATE), EXTRACT(HOUR FROM hr), COUNT(DISTINCT id) AS average_per_hour
FROM generate_series('2014-07-05 00:00:00', '2014-07-06 23:00:00', INTERVAL '1' HOUR) hr
LEFT JOIN search ON date_trunc('hour', startdatetime) = hr
GROUP BY hr
ORDER BY hr