Postgresql 计算离散值的连续出现次数
我有下表,我想计算每个名字和每个标志的连续天数Postgresql 计算离散值的连续出现次数,postgresql,gaps-and-islands,Postgresql,Gaps And Islands,我有下表,我想计算每个名字和每个标志的连续天数 Name Date Flag ------------------------------------- Alberta 01-01-2018 B Alberta 02-01-2018 B Alberta 03-01-2018 B Alberta 04-01-2018 L Alberta 05-01-2018 L
Name Date Flag
-------------------------------------
Alberta 01-01-2018 B
Alberta 02-01-2018 B
Alberta 03-01-2018 B
Alberta 04-01-2018 L
Alberta 05-01-2018 L
Ambelos 01-01-2018 B
Ambelos 02-01-2018 B
Ambelos 03-01-2018 L
Ambelos 04-01-2018 B
我想要下面的
Name Date Flag CountDays
----------------------------------------------------
Alberta 03-01-2018 B 3
Alberta 05-01-2018 L 2
Ambelos 02-01-2018 B 2
Ambelos 03-01-2018 L 1
Ambelos 04-01-2018 B 1
我怎样才能做到这一点呢?你可以使用这种技术
PostgreSQL 9.6架构设置:
CREATE TABLE t
(Name varchar(7), dt timestamp, Flag varchar(1))
;
INSERT INTO t
(Name, dt, Flag)
VALUES
('Alberta', '2018-01-01 00:00:00', 'B'),
('Alberta', '2018-02-01 00:00:00', 'B'),
('Alberta', '2018-03-01 00:00:00', 'B'),
('Alberta', '2018-04-01 00:00:00', 'L'),
('Alberta', '2018-05-01 00:00:00', 'L'),
('Ambelos', '2018-01-01 00:00:00', 'B'),
('Ambelos', '2018-02-01 00:00:00', 'B'),
('Ambelos', '2018-03-01 00:00:00', 'L'),
('Ambelos', '2018-04-01 00:00:00', 'B')
;
SELECT name,
Max(dt) AS "Date",
flag,
Count(*) As CountDays
FROM (SELECT t.*,
row_number()
over (
PARTITION BY name
ORDER BY dt ) - row_number()
over (
PARTITION BY name, flag
ORDER BY dt ) AS seq
FROM t) s
GROUP BY name,
flag,
seq
ORDER BY name,"Date"
| name | Date | flag | countdays |
|---------|----------------------|------|-----------|
| Alberta | 2018-03-01T00:00:00Z | B | 3 |
| Alberta | 2018-05-01T00:00:00Z | L | 2 |
| Ambelos | 2018-02-01T00:00:00Z | B | 2 |
| Ambelos | 2018-03-01T00:00:00Z | L | 1 |
| Ambelos | 2018-04-01T00:00:00Z | B | 1 |
查询1:
CREATE TABLE t
(Name varchar(7), dt timestamp, Flag varchar(1))
;
INSERT INTO t
(Name, dt, Flag)
VALUES
('Alberta', '2018-01-01 00:00:00', 'B'),
('Alberta', '2018-02-01 00:00:00', 'B'),
('Alberta', '2018-03-01 00:00:00', 'B'),
('Alberta', '2018-04-01 00:00:00', 'L'),
('Alberta', '2018-05-01 00:00:00', 'L'),
('Ambelos', '2018-01-01 00:00:00', 'B'),
('Ambelos', '2018-02-01 00:00:00', 'B'),
('Ambelos', '2018-03-01 00:00:00', 'L'),
('Ambelos', '2018-04-01 00:00:00', 'B')
;
SELECT name,
Max(dt) AS "Date",
flag,
Count(*) As CountDays
FROM (SELECT t.*,
row_number()
over (
PARTITION BY name
ORDER BY dt ) - row_number()
over (
PARTITION BY name, flag
ORDER BY dt ) AS seq
FROM t) s
GROUP BY name,
flag,
seq
ORDER BY name,"Date"
| name | Date | flag | countdays |
|---------|----------------------|------|-----------|
| Alberta | 2018-03-01T00:00:00Z | B | 3 |
| Alberta | 2018-05-01T00:00:00Z | L | 2 |
| Ambelos | 2018-02-01T00:00:00Z | B | 2 |
| Ambelos | 2018-03-01T00:00:00Z | L | 1 |
| Ambelos | 2018-04-01T00:00:00Z | B | 1 |
:
CREATE TABLE t
(Name varchar(7), dt timestamp, Flag varchar(1))
;
INSERT INTO t
(Name, dt, Flag)
VALUES
('Alberta', '2018-01-01 00:00:00', 'B'),
('Alberta', '2018-02-01 00:00:00', 'B'),
('Alberta', '2018-03-01 00:00:00', 'B'),
('Alberta', '2018-04-01 00:00:00', 'L'),
('Alberta', '2018-05-01 00:00:00', 'L'),
('Ambelos', '2018-01-01 00:00:00', 'B'),
('Ambelos', '2018-02-01 00:00:00', 'B'),
('Ambelos', '2018-03-01 00:00:00', 'L'),
('Ambelos', '2018-04-01 00:00:00', 'B')
;
SELECT name,
Max(dt) AS "Date",
flag,
Count(*) As CountDays
FROM (SELECT t.*,
row_number()
over (
PARTITION BY name
ORDER BY dt ) - row_number()
over (
PARTITION BY name, flag
ORDER BY dt ) AS seq
FROM t) s
GROUP BY name,
flag,
seq
ORDER BY name,"Date"
| name | Date | flag | countdays |
|---------|----------------------|------|-----------|
| Alberta | 2018-03-01T00:00:00Z | B | 3 |
| Alberta | 2018-05-01T00:00:00Z | L | 2 |
| Ambelos | 2018-02-01T00:00:00Z | B | 2 |
| Ambelos | 2018-03-01T00:00:00Z | L | 1 |
| Ambelos | 2018-04-01T00:00:00Z | B | 1 |
你可以使用技术
PostgreSQL 9.6架构设置:
CREATE TABLE t
(Name varchar(7), dt timestamp, Flag varchar(1))
;
INSERT INTO t
(Name, dt, Flag)
VALUES
('Alberta', '2018-01-01 00:00:00', 'B'),
('Alberta', '2018-02-01 00:00:00', 'B'),
('Alberta', '2018-03-01 00:00:00', 'B'),
('Alberta', '2018-04-01 00:00:00', 'L'),
('Alberta', '2018-05-01 00:00:00', 'L'),
('Ambelos', '2018-01-01 00:00:00', 'B'),
('Ambelos', '2018-02-01 00:00:00', 'B'),
('Ambelos', '2018-03-01 00:00:00', 'L'),
('Ambelos', '2018-04-01 00:00:00', 'B')
;
SELECT name,
Max(dt) AS "Date",
flag,
Count(*) As CountDays
FROM (SELECT t.*,
row_number()
over (
PARTITION BY name
ORDER BY dt ) - row_number()
over (
PARTITION BY name, flag
ORDER BY dt ) AS seq
FROM t) s
GROUP BY name,
flag,
seq
ORDER BY name,"Date"
| name | Date | flag | countdays |
|---------|----------------------|------|-----------|
| Alberta | 2018-03-01T00:00:00Z | B | 3 |
| Alberta | 2018-05-01T00:00:00Z | L | 2 |
| Ambelos | 2018-02-01T00:00:00Z | B | 2 |
| Ambelos | 2018-03-01T00:00:00Z | L | 1 |
| Ambelos | 2018-04-01T00:00:00Z | B | 1 |
查询1:
CREATE TABLE t
(Name varchar(7), dt timestamp, Flag varchar(1))
;
INSERT INTO t
(Name, dt, Flag)
VALUES
('Alberta', '2018-01-01 00:00:00', 'B'),
('Alberta', '2018-02-01 00:00:00', 'B'),
('Alberta', '2018-03-01 00:00:00', 'B'),
('Alberta', '2018-04-01 00:00:00', 'L'),
('Alberta', '2018-05-01 00:00:00', 'L'),
('Ambelos', '2018-01-01 00:00:00', 'B'),
('Ambelos', '2018-02-01 00:00:00', 'B'),
('Ambelos', '2018-03-01 00:00:00', 'L'),
('Ambelos', '2018-04-01 00:00:00', 'B')
;
SELECT name,
Max(dt) AS "Date",
flag,
Count(*) As CountDays
FROM (SELECT t.*,
row_number()
over (
PARTITION BY name
ORDER BY dt ) - row_number()
over (
PARTITION BY name, flag
ORDER BY dt ) AS seq
FROM t) s
GROUP BY name,
flag,
seq
ORDER BY name,"Date"
| name | Date | flag | countdays |
|---------|----------------------|------|-----------|
| Alberta | 2018-03-01T00:00:00Z | B | 3 |
| Alberta | 2018-05-01T00:00:00Z | L | 2 |
| Ambelos | 2018-02-01T00:00:00Z | B | 2 |
| Ambelos | 2018-03-01T00:00:00Z | L | 1 |
| Ambelos | 2018-04-01T00:00:00Z | B | 1 |
:
CREATE TABLE t
(Name varchar(7), dt timestamp, Flag varchar(1))
;
INSERT INTO t
(Name, dt, Flag)
VALUES
('Alberta', '2018-01-01 00:00:00', 'B'),
('Alberta', '2018-02-01 00:00:00', 'B'),
('Alberta', '2018-03-01 00:00:00', 'B'),
('Alberta', '2018-04-01 00:00:00', 'L'),
('Alberta', '2018-05-01 00:00:00', 'L'),
('Ambelos', '2018-01-01 00:00:00', 'B'),
('Ambelos', '2018-02-01 00:00:00', 'B'),
('Ambelos', '2018-03-01 00:00:00', 'L'),
('Ambelos', '2018-04-01 00:00:00', 'B')
;
SELECT name,
Max(dt) AS "Date",
flag,
Count(*) As CountDays
FROM (SELECT t.*,
row_number()
over (
PARTITION BY name
ORDER BY dt ) - row_number()
over (
PARTITION BY name, flag
ORDER BY dt ) AS seq
FROM t) s
GROUP BY name,
flag,
seq
ORDER BY name,"Date"
| name | Date | flag | countdays |
|---------|----------------------|------|-----------|
| Alberta | 2018-03-01T00:00:00Z | B | 3 |
| Alberta | 2018-05-01T00:00:00Z | L | 2 |
| Ambelos | 2018-02-01T00:00:00Z | B | 2 |
| Ambelos | 2018-03-01T00:00:00Z | L | 1 |
| Ambelos | 2018-04-01T00:00:00Z | B | 1 |
对于相同的名称和标志,可以有两个或更多的天数序列?例如,从1月1日到3日-第一个序列和从5日到08年1月-第二个序列,结果表中将有两行相同的名称和标志。是的,如果我理解您的意思,可能会发生这种情况。请检查我的答案,如果答案对您有效,请接受。请阅读:了解为什么它很重要。对于相同的名称和标志,可以是2天或更长的时间序列?例如,从1月1日到3日-第一个序列和从5日到08年1月-第二个序列,结果表中将有两行相同的名称和标志。是的,如果我理解您的意思,可能会发生这种情况。请检查我的答案,如果答案对您有效,请接受。请阅读:来理解为什么它很重要。@VanessaZorgia:不客气。请读:@VanessaZorgia:不客气。请阅读: