SQL查询从多个排名/组中选择第一个排名1行

rst*_*ech 2 sql oracle oracle10g dense-rank

我有以下数据

表格1

id   col1    col2       col3
----------------------------------
1    abc   01/01/2012    -
1    abc   01/01/2012    A
2    abc   01/01/2012    -
2    abc   01/02/2012    -
3    abc   01/02/2012    -
3    xyz   01/01/2012    -
4    abc   01/02/2012    -
4    xyz   01/01/2012    -
4    xyz   01/02/2012    -
Run Code Online (Sandbox Code Playgroud)

以下是评估的顺序 -

if(col1 is false) then evaluate col2 if(col2 is false) then col3:

Col1 - xyz has first preference from all values in this column
col2 - min date
col3 - not '-' or min(col3)
Run Code Online (Sandbox Code Playgroud)

我想为每个id只返回一行,如果col1失败则转到col2,如果失败则转到col3条件.从上面的表结果应该是

 id   col1    col2       col3
----------------------------------
 1    abc     01/01/2012  A
 2    abc     01/01/2012  -
 3    xyz     01/01/2012  -
 4    xyz     01/01/2012  -
Run Code Online (Sandbox Code Playgroud)

我尝试使用密集等级,但它没有帮助.我不确定如何使用任何可用的函数或sql逻辑来执行此逻辑.

for col1 - if more than one row for same code or xyz code then fail
for col2 - if more than one row with same min date then fail 
           [use this only if col1 condition fails]
Run Code Online (Sandbox Code Playgroud)

Jus*_*ave 6

您可以在分析函数中指定许多条件

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
Run Code Online (Sandbox Code Playgroud)

假设dense_rank您使用了dense_rank标签,我假设您需要.你不说说你想如何处理关系或是否关系甚至可能的,所以是否要使用它不是从问题本身清晰rank,dense_rankrow_number分析功能.如果您只获取每个排名最高的行id,rank并且dense_rank行为相同,并且如果第一个地方存在关联,则会返回多行. row_number通过任意打破平局总是会返回一行.如果你想获取除第一行以外的行id,那么你需要考虑关系,你将从rank和获得不同的行为dense_rank.如果首先绑定两行,dense_rank则将第3行分配rnk为2,而rank将其分配rnk为3.

这似乎适用于您发布的示例数据

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
Run Code Online (Sandbox Code Playgroud)