My question is 90% the same as the one below, but with a twist that makes it a bit more complicated: Merge rows postgres and replace values with latest when not null
The difference is that in the original question the max(case when slug is not null then id end) slugid was also what should be joined on, but for me the join should happen based on the value of another column.
Example documents table (contracts to documents is a 1:many relationship):
| id | contract_id | timestamp | a | b | c |
|---|---|---|---|---|---|
| UUID-C | UUID-A | 2021-08-18 10:00 | X | Y | Z |
| UUID-D | UUID-A | 2021-08-18 11:00 | null | F | null |
| UUID-E | UUID-B | 2021-08-18 11:00 | F | null | null |
| UUID-F | UUID-B | 2021-08-18 12:00 | null | G | null |
| UUID-G | UUID-B | 2021-08-18 13:00 | X | null | H |
Expected result:
| contract_id | a | b | c |
|---|---|---|---|
| UUID-A | X | F | Z |
| UUID-B | X | G | H |
The documents column that should be used for determining the most recent (and therefore, most important) row is timestamp, but the documents.id should be used for merging the results instead of the timestamp in order to prevent unexpected behaviour.
An example of how the most recent timestamps are selected for each a, b, c value is this:
SELECT
contract_id,
max(case when a is not null then timestamp end) a_timestamp,
max(case when b is not null then timestamp end) b_timestamp,
max(case when c is not null then timestamp end) c_timestamp,
FROM documents
GROUP BY contract_id;
but then the join should happen based on id, not on timestamp.
How do I do this?