SQL FIDDLE
我有以下数据库表:
日期 | 名称 | |
---|---|---|
2014-08-10 | bob | |
2014-08-10 | 起诉 | |
2014-08-11 | bob | |
2014-08-11 | 麦克风 | |
2014-08-12 | bob | |
2014-08-12 | 麦克风 | |
2014-08-05 | bob | |
2014-08-06 | bob |
您使用了错误的逻辑。基本上,你想要的日期是连续的,所以你想从日期中减去序列:
SELECT t.Name, COUNT(*) as frequency
FROM (SELECT o.*,
row_number() OVER (PARTITION BY Name ORDER BY Date) as seqnum
FROM orders o
) t
GROUP BY Name, date - seqnum * interval '1 day';
这里有一个db<gt;不停摆弄
Postgresql中Date数据类型Demo1的缺口和孤岛问题:运行此:
drop table if exists foobar;
CREATE TABLE foobar( tick text, date_val date );
insert into foobar values('XYZ', '2021-01-03'); --island 1 has width 2
insert into foobar values('XYZ', '2021-01-04'); --island 1
insert into foobar values('XYZ', '2021-05-09'); --island 2 has width 3
insert into foobar values('XYZ', '2021-05-10'); --island 2
insert into foobar values('XYZ', '2021-05-11'); --island 2
insert into foobar values('XYZ', '2021-07-07'); --island 3 has width 4
insert into foobar values('XYZ', '2021-07-08'); --island 3
insert into foobar values('XYZ', '2021-07-09'); --island 3
insert into foobar values('XYZ', '2021-07-10'); --island 3
insert into foobar values('XYZ', '2022-10-10'); --island 4 has width 1
select * from foobar;
select tick, island_width, min_val, max_val,
min_val - lag(max_val) over (order by max_val)
as gap_width from
(
select tick, count(*) as island_width,
min(date_val) min_val, max(date_val) max_val
from (
select t.*,
row_number() over ( partition by tick order by date_val ) as seqnum
from foobar t where tick = 'XYZ'
) t
group by tick, date_val - seqnum * interval '1 day'
) t2 order by max_val desc
按顺序打印日期的间隙和孤岛:
┌──────┬────────────┐
│ tick │ date_val │
├──────┼────────────┤
│ XYZ │ 2021-01-03 │
│ XYZ │ 2021-01-04 │
│ XYZ │ 2021-05-09 │
│ XYZ │ 2021-05-10 │
│ XYZ │ 2021-05-11 │
│ XYZ │ 2021-07-07 │
│ XYZ │ 2021-07-08 │
│ XYZ │ 2021-07-09 │
│ XYZ │ 2021-07-10 │
│ XYZ │ 2022-10-10 │
└──────┴────────────┘
┌──────┬──────────────┬────────────┬────────────┬───────────┐
│ tick │ island_width │ min_val │ max_val │ gap_width │
├──────┼──────────────┼────────────┼────────────┼───────────┤
│ XYZ │ 1 │ 2022-10-10 │ 2022-10-10 │ 457 │
│ XYZ │ 4 │ 2021-07-07 │ 2021-07-10 │ 57 │
│ XYZ │ 3 │ 2021-05-09 │ 2021-05-11 │ 125 │
│ XYZ │ 2 │ 2021-01-03 │ 2021-01-04 │ ¤ │
└──────┴──────────────┴────────────┴────────────┴───────────┘
列island_width
给出了连续数据的宽度。gap_width为您提供缺失数据的宽度。
Postgresql中Integer数据类型Demo2的缺口和孤岛问题:
运行此:
drop table if exists foobar;
CREATE TABLE foobar( tick text, the_value int);
insert into foobar values('XYZ', -5); --island 1 has width 2
insert into foobar values('XYZ', -4); --end island 1
insert into foobar values('XYZ', 0); --island 2 has width 3
insert into foobar values('XYZ', 1); --island 2
insert into foobar values('XYZ', 2); --end island 2
insert into foobar values('XYZ', 34); --island 3 has width 4
insert into foobar values('XYZ', 35); --island 3
insert into foobar values('XYZ', 36); --island 3
insert into foobar values('XYZ', 37); --island 3
insert into foobar values('XYZ', 85); --island 4 has width 1
select * from foobar;
select tick, island_width, min_val, max_val,
min_val - lag(max_val) over (order by max_val)
as gap_width from
(
select tick, count(*) as island_width,
min(the_value) min_val, max(the_value) max_val
from (
select t.*,
row_number() over ( partition by tick order by the_value) as seqnum
from foobar t where tick = 'XYZ'
) t
group by tick, the_value - seqnum * 1
) t2 order by max_val desc
按顺序打印整数列的间隙和孤岛:
┌──────┬───────────┐
│ tick │ the_value │
├──────┼───────────┤
│ XYZ │ -5 │
│ XYZ │ -4 │
│ XYZ │ 0 │
│ XYZ │ 1 │
│ XYZ │ 2 │
│ XYZ │ 34 │
│ XYZ │ 35 │
│ XYZ │ 36 │
│ XYZ │ 37 │
│ XYZ │ 85 │
└──────┴───────────┘
┌──────┬──────────────┬─────────┬─────────┬───────────┐
│ tick │ island_width │ min_val │ max_val │ gap_width │
├──────┼──────────────┼─────────┼─────────┼───────────┤
│ XYZ │ 1 │ 85 │ 85 │ 48 │
│ XYZ │ 4 │ 34 │ 37 │ 32 │
│ XYZ │ 3 │ 0 │ 2 │ 4 │
│ XYZ │ 2 │ -5 │ -4 │ ¤ │
└──────┴──────────────┴─────────┴─────────┴───────────┘
列island_width
给出了连续数据的宽度。gap_width
为您提供缺失数据的宽度。这允许你说:";让我看看岛与岛之间的空隙";或";给我看岛的大小和开始/停止位置";