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.
This query is easy convert to MS SQL. If you need more something specific add comment. Mysql Query:
SQLFIDDLEExample
Result:
"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 toDISTINCT
in the standard. Replace the finalSELECT
with 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
id
we need to fill all columns.