Maak de tabel en de voorbeelddatum
SQL> create table observation(
2 item_id number,
3 dt date,
4 val1 number,
5 val2 number );
Table created.
SQL> insert into observation values( 1, date '2011-12-01', 1, null );
1 row created.
SQL> insert into observation values( 1, date '2011-12-02', null, 2 );
1 row created.
SQL> insert into observation values( 1, date '2011-12-03', 3, null );
1 row created.
SQL> insert into observation values( 2, date '2011-12-01', 4, null );
1 row created.
SQL> insert into observation values( 2, date '2011-12-02', 5, 6 );
1 row created.
En gebruik dan de KEEP
clausule op de MAX
aggregatiefunctie met een ORDER BY
dat zet de rijen met NULL-waarnemingen aan het einde. welke datum je ook gebruikt in de ORDER BY
moet eerder zijn dan de vroegste echte waarneming in de tabel.
SQL> ed
Wrote file afiedt.buf
1 select item_id,
2 max(val1) keep( dense_rank last
3 order by (case when val1 is not null
4 then dt
5 else date '1900-01-01'
6 end) ) val1,
7 max(val2) keep( dense_rank last
8 order by (case when val2 is not null
9 then dt
10 else date '1900-01-01'
11 end) ) val2
12 from observation
13* group by item_id
SQL> /
ITEM_ID VAL1 VAL2
---------- ---------- ----------
1 3 2
2 5 6
Ik vermoed dat er een elegantere oplossing is om de NULL-waarden te negeren dan het toevoegen van de CASE
statement naar de ORDER BY
maar de CASE
klaart de klus.