Select 具有重叠条件的不同记录
Select Distinct Records with overlapping conditions
我想查询 select '2017-01-01' 和 '2017-03-01' 之间的日期计数
无论如何,是否可以在不使用 case 语句的情况下分别计算“2017-01-01”、“2017-02-01”和“2017-03-01”。
有点像使用 group by
SELECT date, count(*) FROM table WHERE date>='2017-01-01' AND date<='2017-03-01' GROUP BY date;
或者您可以更改包含或不包含的日期
您需要函数 date_trunc
。它会将您的 dates/timestamps 截断为月份。
daniel=> select date_trunc('month', '2017-01-31'::date);
date_trunc
---------------------
2017-01-01 00:00:00
(1 row)
daniel=> select date_trunc('month', '2017-03-17'::date);
date_trunc
---------------------
2017-03-01 00:00:00
(1 row)
即查询将类似于:
SELECT
date_trunc('month', date) as 'month',
count(*) as 'count'
FROM
table
WHERE
date_trunc('month', date) >= '2017-01-01'
AND
date_trunc('month', date) <= '2017-03-01'
GROUP BY
date_trunc('month', date);
如果您需要生成时间序列,请在 row_number() over ()
和任何具有足够行的 table 中使用,例如 system_tables
:
daniel=> select '2017-01-01'::DATE + cast(row_number() over () - 1 as interval month) from system_tables limit 5;
?column?
---------------------
2017-01-01 00:00:00
2017-02-01 00:00:00
2017-03-01 00:00:00
2017-04-01 00:00:00
2017-05-01 00:00:00
(5 rows)
您也可以尝试 TIMESERIES
填充间隙:
SELECT ts AS 'date' FROM (
SELECT '2017-01-01'::TIMESTAMP AS tm
UNION
SELECT '2017-01-03'::TIMESTAMP AS tm) AS t
TIMESERIES ts AS '8 hours' OVER (ORDER BY tm);
daniel=> \e
date
---------------------
2017-01-01 00:00:00
2017-01-01 08:00:00
2017-01-01 16:00:00
2017-01-02 00:00:00
2017-01-02 08:00:00
2017-01-02 16:00:00
2017-01-03 00:00:00
(7 rows)
现在,让我们将所有内容组合在一起,计算每个月的天数 date_trunc
:
SELECT
date_trunc('month', T.date) AS 'MONTH',
count(*) AS 'COUNT'
FROM (
SELECT ts::DATE AS 'date' FROM (
SELECT '2017-01-01'::TIMESTAMP AS tm
UNION ALL
SELECT '2017-03-01'::TIMESTAMP AS tm
) AS S
TIMESERIES ts AS '8 hours' OVER (ORDER BY tm)
) AS T
GROUP BY 1
ORDER BY 1;
daniel=> \e
MONTH | COUNT
---------------------+-------
2017-01-01 00:00:00 | 93
2017-02-01 00:00:00 | 84
2017-03-01 00:00:00 | 1
(3 rows)
我想查询 select '2017-01-01' 和 '2017-03-01' 之间的日期计数 无论如何,是否可以在不使用 case 语句的情况下分别计算“2017-01-01”、“2017-02-01”和“2017-03-01”。
有点像使用 group by
SELECT date, count(*) FROM table WHERE date>='2017-01-01' AND date<='2017-03-01' GROUP BY date;
或者您可以更改包含或不包含的日期
您需要函数 date_trunc
。它会将您的 dates/timestamps 截断为月份。
daniel=> select date_trunc('month', '2017-01-31'::date);
date_trunc
---------------------
2017-01-01 00:00:00
(1 row)
daniel=> select date_trunc('month', '2017-03-17'::date);
date_trunc
---------------------
2017-03-01 00:00:00
(1 row)
即查询将类似于:
SELECT
date_trunc('month', date) as 'month',
count(*) as 'count'
FROM
table
WHERE
date_trunc('month', date) >= '2017-01-01'
AND
date_trunc('month', date) <= '2017-03-01'
GROUP BY
date_trunc('month', date);
如果您需要生成时间序列,请在 row_number() over ()
和任何具有足够行的 table 中使用,例如 system_tables
:
daniel=> select '2017-01-01'::DATE + cast(row_number() over () - 1 as interval month) from system_tables limit 5;
?column?
---------------------
2017-01-01 00:00:00
2017-02-01 00:00:00
2017-03-01 00:00:00
2017-04-01 00:00:00
2017-05-01 00:00:00
(5 rows)
您也可以尝试 TIMESERIES
填充间隙:
SELECT ts AS 'date' FROM (
SELECT '2017-01-01'::TIMESTAMP AS tm
UNION
SELECT '2017-01-03'::TIMESTAMP AS tm) AS t
TIMESERIES ts AS '8 hours' OVER (ORDER BY tm);
daniel=> \e
date
---------------------
2017-01-01 00:00:00
2017-01-01 08:00:00
2017-01-01 16:00:00
2017-01-02 00:00:00
2017-01-02 08:00:00
2017-01-02 16:00:00
2017-01-03 00:00:00
(7 rows)
现在,让我们将所有内容组合在一起,计算每个月的天数 date_trunc
:
SELECT
date_trunc('month', T.date) AS 'MONTH',
count(*) AS 'COUNT'
FROM (
SELECT ts::DATE AS 'date' FROM (
SELECT '2017-01-01'::TIMESTAMP AS tm
UNION ALL
SELECT '2017-03-01'::TIMESTAMP AS tm
) AS S
TIMESERIES ts AS '8 hours' OVER (ORDER BY tm)
) AS T
GROUP BY 1
ORDER BY 1;
daniel=> \e
MONTH | COUNT
---------------------+-------
2017-01-01 00:00:00 | 93
2017-02-01 00:00:00 | 84
2017-03-01 00:00:00 | 1
(3 rows)