通过创建不仅是一个系列,而是一组的第1天的范围,任何时间戳数据可以使用加入到范围> =与<
特别要注意,这种方法避免了数据上的函数(比如截断日期),并且因此它允许使用索引来帮助查询性能。
如果一些数据是这样的:
CREATE TABLE my_data
("data_dt" timestamp)
;
INSERT INTO my_data
("data_dt")
VALUES
('2014-09-01 08:24:00'),
('2014-09-01 22:48:00'),
('2014-09-02 13:12:00'),
('2014-09-03 03:36:00'),
('2014-09-03 18:00:00'),
然后可接合,使用outer join
所以不匹配的范围仍报告给产生的范围集合(dt_start & dt_end对)
SELECT
r.dt_start
, count(d.data_dt)
FROM (
SELECT
dt_start
, dt_start + INTERVAL '1 Day' dt_end
FROM
generate_series('2014-09-01 00:00'::timestamp,
'2014-09-30 00:00', '1 Day') AS dt_start
) AS r
LEFT OUTER JOIN my_data d ON d.data_dt >= r.dt_start
AND d.data_dt < r.dt_end
GROUP BY
r.dt_start
ORDER BY
r.dt_start
;
并产生如下结果:
| DT_START | COUNT |
|----------------------------------|-------|
| September, 01 2014 00:00:00+0000 | 2 |
| September, 02 2014 00:00:00+0000 | 1 |
| September, 03 2014 00:00:00+0000 | 2 |
| September, 04 2014 00:00:00+0000 | 2 |
...
| September, 29 2014 00:00:00+0000 | 0 |
| September, 30 2014 00:00:00+0000 | 0 |
See this SQLFiddle demo
是否有理由不能使用convert/cast + BETWEEN? – ilitirit 2014-09-19 10:57:52
它会计算在几天之内有数据的日期。虽然我需要日期计数行,但在该日期的哪一天,每个月的每一天都是列 – Nazerke 2014-09-19 11:08:39