I have a sqlite table with data similar to the following:
x
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 |