CREATE TABLE entries (
id serial NOT NULL,
title character varying,
load_sequence integer
);
and data
INSERT INTO entries(title, load_sequence) VALUES ('A', 1);
INSERT INTO entries(title, load_sequence) VALUES ('A', 2);
INSERT INTO entries(title, load_sequence) VALUES ('A', 3);
INSERT INTO entries(title, load_sequence) VALUES ('A', 6);
INSERT INTO entries(title, load_sequence) VALUES ('B', 4);
INSERT INTO entries(title, load_sequence) VALUES ('B', 5);
INSERT INTO entries(title, load_sequence) VALUES ('B', 7);
INSERT INTO entries(title, load_sequence) VALUES ('B', 8);
Is there a way in PostgreSQL to write SQL that groups data by same title
segments after ordering them by load_sequence
.
I mean:
=# SELECT id, title, load_sequence FROM entries ORDER BY load_sequence;
id | title | load_sequence
----+-------+---------------
9 | A | 1
10 | A | 2
11 | A | 3
13 | B | 4
14 | B | 5
12 | A | 6
15 | B | 7
16 | B | 8
AND I want groups:
=# SELECT title, string_agg(id::text, ',' ORDER BY id) FROM entries ???????????;
so result would be:
title | string_agg
-------+-------------
A | 9,10,11
B | 13,14
A | 12
B | 15,16
You can use the following query:
SELECT title, string_agg(id::text, ',' ORDER BY id)
FROM (
SELECT id, title,
ROW_NUMBER() OVER (ORDER BY load_sequence) -
ROW_NUMBER() OVER (PARTITION BY title
ORDER BY load_sequence) AS grp
FROM entries ) AS t
GROUP BY title, grp
Calculated grp
field serves to identify slices of title
records having consecutive load_sequence
values. Using this field in the GROUP BY
clause we can achieve the required aggregation over id
values.
Demo here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With