我有以下数据
表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]
答案 0 :(得分: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
假设您使用dense_rank
标记,我认为您需要dense_rank
。你没有谈论你想如何处理关系或者关系是否可能,所以从问题本身就不清楚你是否想要使用rank
,dense_rank
或{{1}分析函数。如果您只是按row_number
获取排名最高的行,id
和rank
的行为相同,如果第一个地方有联系,则会返回多行。 dense_rank
总是通过任意打破平局返回一行。如果您想要按row_number
获取第一行以外的行,那么您需要考虑关系,并且您将从id
和rank
获得不同的行为。如果首先绑定两行,dense_rank
将为第三行分配dense_rank
为2,而rnk
将为其分配rank
为3。
这似乎适用于您发布的示例数据
rnk
答案 1 :(得分:0)
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