Du kan angive mange betingelser for at bestille efter i din analytiske funktion
SELECT *
FROM (SELECT id,
col1,
col2,
col3,
dense_rank() over (partition by id
order by (case when col1 = 'xyz'
then 1
else 0
end) desc,
col2 asc,
col3 asc) rnk
FROM your_table)
WHERE rnk = 1
Jeg går ud fra, at du vil have dense_rank
givet at du brugte dense_rank
tag. Man taler ikke om, hvordan man vil håndtere slips, eller om slips overhovedet er muligt, så det fremgår ikke af selve spørgsmålet, om man vil bruge rank
, dense_rank
eller row_number
analytiske funktioner. Hvis du kun henter den højest rangerende række pr. id
, rank
og dense_rank
vil opføre sig identisk og vil returnere flere rækker, hvis der er uafgjort på førstepladsen. row_number
vil altid returnere en enkelt række ved vilkårligt at bryde uafgjort. Hvis du vil hente andre rækker end den første række pr. id
, så bliver du nødt til at tænke på bånd, og du vil få anderledes adfærd fra rank
og dense_rank
. Hvis to rækker er lige først, dense_rank
vil tildele den tredje række en rnk
af 2, mens rank
vil tildele den en rnk
af 3.
Dette ser ud til at fungere for de eksempeldata, du har sendt
SQL> ed
Wrote file afiedt.buf
1 with x as (
2 select 1 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
3 select 1 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, 'A' col3 from dual union all
4 select 2 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
5 select 2 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
6 select 3 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
7 select 3 id, 'xyz' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
8 select 4 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
9 select 4 id, 'xyz' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
10 select 4 id, 'xyz' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual
11 )
12 SELECT *
13 FROM (SELECT id,
14 col1,
15 col2,
16 col3,
17 dense_rank() over (partition by id
18 order by (case when col1 = 'xyz'
19 then 1
20 else 0
21 end) desc,
22 col2 asc,
23 col3 asc) rnk
24 FROM x)
25* WHERE rnk = 1
SQL> /
ID COL COL2 C RNK
---------- --- --------- - ----------
1 abc 01-JAN-12 A 1
2 abc 01-JAN-12 1
3 xyz 01-JAN-12 1
4 xyz 01-JAN-12 1