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