如何在 Postgres 中查找连续的日期 SQL
How to Find Consecutive Dates in Postgres SQL
我在 postgres 数据库中有以下 table(table 名称是 table_test):
id dia Data_sensor_Analog
2165 2020-09-20 4585542
2165 2020-09-21 4954566
2165 2020-09-26 255
我想统计连续多少天有属性dia
。
为此,我尝试编写了以下代码:
WITH
groups AS (
SELECT
ROW_NUMBER() OVER (ORDER BY dia) AS rn,
dateadd(dia, -ROW_NUMBER() OVER (ORDER BY dia), dia) AS grp,
dia
FROM table_test
)
SELECT
COUNT(*) AS consecutiveDates,
MIN(dia) AS minDate,
MAX(dia) AS maxDate
FROM groups
GROUP BY grp
ORDER BY 1 DESC, 2 DESC
我希望输出为:
consecutiveDates minDate maxDate
1 2020-09-20 2020-09-21
但是,当我运行代码时,出现如下错误信息:
ERROR: function dateadd(text, bigint, text) does not exist
LINE 17: dateadd(dia, -ROW_NUMBER() OVER (ORDER BY dia), dia) A
我正在使用 postgres,并在网站上找到了这个示例代码:https://blog.jooq.org/2015/11/07/how-to-find-the-longest-consecutive-series-of-events-in-sql/
我将 dia
属性转换为:
ALTER TABLE table_test
ALTER COLUMN dia
TYPE TIMESTAMP WITHOUT TIME ZONE
USING dia::timestamp without time zone;
你可以减去一个枚举值,但你需要一个子查询或CTE:
select min(dia), max(dia), count(*)
from (select t.*,
row_number() over (order by dia) as seqnum
from table_test t
) t
group by dia - seqnum * interval '1 day';
但是,看起来 dia
是一个字符串而不是日期。要解决这个问题:
group by (dia::date) - seqnum * interval '1 day';
格式适合转换为日期。
Here 是一个 db<>fiddle.
考虑到您的 table 中一天只有一个条目,那么试试这个:
select id, count(*) -1 "count", max(dia), min(dia) from (
select *,
date(dia) - row_number() over (partition by id order by date(dia)) * interval '1 day' "filter"
from table_test
) t1
group by id, filter
having count(*) -1 > 0
如果同一日期有多个值,请尝试以下操作:
with cte as (
select
*,
date(dia) date_,date(dia) - dense_rank() over ( partition by id order by date(dia)) * interval '1 day' "filter"
from table_test
)
select
id, count(distinct date_) -1 "count" , max(dia),min(dia)
from cte
group by id, filter
having count(distinct date_) -1 >0
我在 postgres 数据库中有以下 table(table 名称是 table_test):
id dia Data_sensor_Analog
2165 2020-09-20 4585542
2165 2020-09-21 4954566
2165 2020-09-26 255
我想统计连续多少天有属性dia
。
为此,我尝试编写了以下代码:
WITH
groups AS (
SELECT
ROW_NUMBER() OVER (ORDER BY dia) AS rn,
dateadd(dia, -ROW_NUMBER() OVER (ORDER BY dia), dia) AS grp,
dia
FROM table_test
)
SELECT
COUNT(*) AS consecutiveDates,
MIN(dia) AS minDate,
MAX(dia) AS maxDate
FROM groups
GROUP BY grp
ORDER BY 1 DESC, 2 DESC
我希望输出为:
consecutiveDates minDate maxDate
1 2020-09-20 2020-09-21
但是,当我运行代码时,出现如下错误信息:
ERROR: function dateadd(text, bigint, text) does not exist
LINE 17: dateadd(dia, -ROW_NUMBER() OVER (ORDER BY dia), dia) A
我正在使用 postgres,并在网站上找到了这个示例代码:https://blog.jooq.org/2015/11/07/how-to-find-the-longest-consecutive-series-of-events-in-sql/
我将 dia
属性转换为:
ALTER TABLE table_test
ALTER COLUMN dia
TYPE TIMESTAMP WITHOUT TIME ZONE
USING dia::timestamp without time zone;
你可以减去一个枚举值,但你需要一个子查询或CTE:
select min(dia), max(dia), count(*)
from (select t.*,
row_number() over (order by dia) as seqnum
from table_test t
) t
group by dia - seqnum * interval '1 day';
但是,看起来 dia
是一个字符串而不是日期。要解决这个问题:
group by (dia::date) - seqnum * interval '1 day';
格式适合转换为日期。
Here 是一个 db<>fiddle.
考虑到您的 table 中一天只有一个条目,那么试试这个:
select id, count(*) -1 "count", max(dia), min(dia) from (
select *,
date(dia) - row_number() over (partition by id order by date(dia)) * interval '1 day' "filter"
from table_test
) t1
group by id, filter
having count(*) -1 > 0
如果同一日期有多个值,请尝试以下操作:
with cte as (
select
*,
date(dia) date_,date(dia) - dense_rank() over ( partition by id order by date(dia)) * interval '1 day' "filter"
from table_test
)
select
id, count(distinct date_) -1 "count" , max(dia),min(dia)
from cte
group by id, filter
having count(distinct date_) -1 >0