我有以下数据
表格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 -
以下是为了评估 -
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)
我想只返回一行每个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 -
我试图用密集的排名,但它并没有帮助。 我不知道如何执行使用任何可用的功能或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]
您可以指定多个条件,你的分析功能,以通过排序
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
我假设你想dense_rank
给您所使用的dense_rank
标签。 你不说说你想如何处理关系或是否关系甚至可能的,所以是否要使用它不是从问题本身清晰的rank
, dense_rank
,或row_number
解析函数。 如果你只取过每排名最高的行id
, rank
和dense_rank
会表现相同,并且将返回多行,如果有第一名的关系。 row_number
总是会被打破任意领带返回一行。 如果你想获取不是每个第一行其他行id
,那么你就需要考虑一下领带,你会从中获取不同的行为rank
和dense_rank
。 如果两行是并列第一, dense_rank
将指派第三行是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
with tmp(id, col1, col2, col3, col1b, col3b) as
(select distinct id, col1, col2, col3,
case when col1 = 'xyz' then '0' else '1' || col1 end,
case when col3 = '-' then '1' else '0' || col3 end
from Table1)
select t1.id, t1.col1, t1.col2, t1.col3
from tmp t1
left join tmp t2 on t1.id = t2.id
and t1.col1b > t2.col1b
left join tmp t3 on t1.id = t3.id
and t1.col1b = t3.col1b
and t1.col2 > t3.col2
left join tmp t4 on t1.id = t4.id
and t1.col1b = t4.col1b
and t1.col2 = t4.col2
and t1.col3b > t4.col3b
where t2.id is null
and t3.id is null
and t4.id is null