我需要根据“级联if条件”的设置从每组项目中选择“前1”记录。
分组基于MovieId,Formatid和Date。
这是我的表的一个例子(稍微分解一下,以突出我试图实现的逻辑的4个“案例”)...
Id | MovieId | FormatId | SourceId | Date | Lock | Created | Modified
------------------------------------------------------------------------------
1 | 1 | 1 | 1 | 2014-03-12 | 1 | 2014-03-12 | NULL
2 | 1 | 1 | 2 | 2014-03-12 | NULL | 2014-03-12 | NULL
3 | 1 | 1 | 3 | 2014-03-12 | NULL | 2014-03-12 | 2014-03-13
4 | 1 | 1 | 4 | 2014-03-12 | NULL | 2014-03-12 | NULL
5 | 1 | 2 | 1 | 2014-03-12 | NULL | 2014-03-12 | NULL
6 | 1 | 2 | 2 | 2014-03-12 | NULL | 2014-03-12 | NULL
7 | 1 | 2 | 3 | 2014-03-12 | NULL | 2014-03-12 | NULL
8 | 1 | 2 | 4 | 2014-03-12 | NULL | 2014-03-12 | NULL
9 | 1 | 3 | 1 | 2014-03-12 | NULL | 2014-03-12 | NULL
10 | 1 | 3 | 3 | 2014-03-12 | NULL | 2014-03-12 | 2014-03-13
11 | 2 | 1 | 2 | 2014-03-12 | NULL | 2014-03-12 | NULL
我的预期结果将是这些行...
1 | 1 | 1 | 1 | 2014-03-12 | 1 | 2014-03-12 | NULL
8 | 1 | 2 | 4 | 2014-03-12 | NULL | 2014-03-12 | NULL
10 | 1 | 3 | 3 | 2014-03-12 | NULL | 2014-03-12 | 2014-03-13
11 | 2 | 1 | 2 | 2014-03-12 | NULL | 2014-03-12 | NULL
所以这是算法(同样,每个MovieId / FormatId / Date组)......
首先,如果有一个SourceId = 1 AND Lock NOT NULL的记录,那么选择那个 其次,如果有一个SourceId = 4的记录,那么选择那个 第三,如果有记录,其中SourceId<> 2,然后选择最近更新的一个 最后,如果只有1个记录,其中SourceId = 2,那么选择那个。
另外两个注释/请求... 1)我已经有一个索引视图执行其中一些并使用带有ROW_NUMBER()的“条件ORDER BY”子句,即
ORDER BY(X结束时的情况)DESC,(然后结束时的情况)......
但这并不完全正确,而且表现可怕! 2)这个表非常大(目前大约有600万行),所以我见过的一些东西推荐用于小型表,但这个表不是其中之一。
提前致谢! - 亨利·
答案 0 :(得分:0)
您的问题只是说:"使用row_number()
,使用row_number()
!"
这会为组中的每一行分配一个序号。行根据order by
排序。为此,只需使用逻辑优先:
select Id, MovieId, FormatId, SourceId, Date, Lock, Created, Modified
from (select t.*,
row_number() over (partition by MovieId, FormatId, Date
order by (case when SourceId = 1 AND Lock NOT NULL then 1
when SourceId = 4 then 2
when SourceId <> 2 then 3
when SourceId = 2 then 4
else 5
end), Modified desc
) as seqnum,
sum(case when SourceId = 2 then 1 else 0 end) over (partition by MovieId, FormatId, Date) as NumSourceId2
from table t
) t
where seqnum = 1 and not (SourceId = 2 and NumSourceId2 > 1);
请注意,如果不满足任何条件,这仍将选择一行。在这种情况下,你没有具体说明该做什么。