This is an extended version of a related previous question. I have posted it a new question for Erwin Brandstetter suggested me to do so. (I realized that I actually wanted this, after people replied to my first question)
Having the following data (blank means NULL):
ID User ColA ColB ColC
1 1 15 20
2 1 11 4
3 1 3
4 2 5 5 10
5 2 6
6 2 8
7 1 1
How can I get the last not-NULL values of each column for all users, the simplest way? So the resulting for the given data would be:
User ColA ColB ColC
1 11 1 20
2 6 8 10
I have not found much, the function that seemed to do something similar to what I describe was COALESCE, but it does not work as expected in my case.
Note: Standard SQL if possible, PostgreSQL otherwise. The count of the involved columns might change, so a solution that is not tied to these three specific columns would be best.
"Standard" SQL
Similar to what I posted on the previous question, a recursive CTE is elegant and probably the fastest way to do it in standard SQL – especially for many rows per user.
-> sqlfiddle for requested PostgreSQL.
The only non-standard element is
DISTINCT ON, which is an extension toDISTINCTin the standard. Replace the finalSELECTwith this for a standard SQL:The request for "standard SQL" is of limited use. The standard only exists on paper. No RDBMS implements 100 % standard SQL – it would be rather pointless, too, since the standard includes nonsensical parts here and there. Arguably, PostgreSQL’s implementation is among the closest to the standard.
PL/pgSQL function
This solution is specific to PostgreSQL, but should perform very well.
I am building on the same table as demonstrated in the fiddle above.
Call:
Returns the whole row – including the min
idwe need to fill all columns.