I have a sqlite table with data similar to the following:
id | flag ----+----- 1 | 0 2 | 0 3 | 1 4 | 0 5 | 1 6 | 0 7 | 1
I’d like to get results that look like the following:
id1 | id2 ----+----- 1 | null 2 | null 3 | 5 4 | null 6 | null 7 | null
To explain, I’m trying to “combine” the id’s of each “pair” of records (in order) where “flag == 1”. Where the record has “flag == 0”, id2 should just be NULL. Also notice, since I have a odd number of records where “flag == 1” (in this example), the final one (id = 7) doesn’t have an additional record to pair with, so it too has an id2 field of NULL.
Is this possible via pure SQL (sqlite3 in this case)? I can obviously post-process the results in the host application, but was hoping to not have to.
*** EDIT ***
Adding the requested MRE…
CREATE TABLE test (
id INTEGER NOT NULL PRIMARY KEY,
flag INTEGER NOT NULL );
INSERT INTO test(flag) VALUES(0),(0),(1),(0),(1),(0),(1);
Advertisement
Answer
You can do it with window functions MIN() and ROW_NUMBER():
SELECT id id1, CASE WHEN flag THEN next END id2
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY flag ORDER BY id) rn,
MIN(CASE WHEN flag THEN id END) OVER (ORDER BY id ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) next
FROM test
)
WHERE flag = 0 OR rn % 2 = 1
ORDER BY id1
See the demo.
Results:
| id1 | id2 |
|---|---|
| 1 | null |
| 2 | null |
| 3 | 5 |
| 4 | null |
| 6 | null |
| 7 | null |