I need a query that will compare the sequences of two columns (from two different tables) and display the first differing result. Summary with details follow:
- Operating out of a PostgreSQL server and using DBeaver
- Two tables with identical column headers.
- One entry (creq_id) will have 36 sequences (seq).
- When the UI modifies the data (chan_id), Table B records the new entry.
- Modification can be a change to original value or a new addition to the sequence.
- Query should compare each sequence (total of 36 sequences) from both tables and stop at the first difference which is recorded in Table B.
Example of changing/overwriting a chan_id:
Table A
creq_id | chan_id | seq |
---|---|---|
29022 | 400 | 1 |
29022 | 0 | 2 |
29022 | 0 | 3 |
Table B
creq_id | chan_id | seq |
---|---|---|
29022 | 500 | 1 |
29022 | 0 | 2 |
29022 | 0 | 3 |
Example of adding a new chan_id
Table A
creq_id | chan_id | seq |
---|---|---|
29022 | 400 | 1 |
29022 | 0 | 2 |
29022 | 0 | 3 |
Table B
creq_id | chan_id | seq |
---|---|---|
29022 | 400 | 1 |
29022 | 500 | 2 |
29022 | 0 | 3 |
In either case above, the result I am seeking:
- Table A.chan_id as orig_value
- Table B.chan_id as new_value
orig_value | new_value |
---|---|
400 | 500 |
Advertisement
Answer
The basic query is to join each table by creq_id and seq_id, then check if their chan_ids are not equal.
To differentiate between a change and an add, if tableA’s chan_id is 0 then it’s a change and we need to use chan_id from the previous sequence. We get that with a subquery.
select a.creq_id, case a.chan_id when 0 then ( -- Get the previous chan_id select chan_id from tablea where creq_id = a.creq_id and seq = a.seq - 1 ) else a.chan_id end as original, b.chan_id as new, a.seq, b.seq from tablea a join tableb b on a.creq_id = b.creq_id and a.seq = b.seq where a.chan_id != b.chan_id
This causes a problem, what if you want to store a 0 then change it? It looks the same as having added a new value. To avoid this, use null
instead of 0 to mean “no value”.
select a.creq_id, coalesce( a.chan_id, ( -- Get the previous chan_id select chan_id from tablea where creq_id = a.creq_id and seq = a.seq - 1 ) ) as original, b.chan_id as new, a.seq, b.seq from tablea a join tableb b on a.creq_id = b.creq_id and a.seq = b.seq -- skip when both columns are null, because null != null where (a.chan_id is null and b.chan_id is not null) or a.chan_id != b.chan_id