TSQL,跨有序组获取前N个唯一行

时间:2017-09-08 15:25:26

标签: sql sql-server tsql

我有以下值表,按用户指定的任意段ID排序。 (我知道如何进行查询,下面是结果)

SegmentID   SequenceID
3           100
3           200
3           400
3           430
1           100
1           200
1           300
1           410
2           100
2           200
2           300
2           420

我需要一个SQL查询(Sql Server 2012),它按优先顺序返回前N个记录,其中不重复SequenceID。

示例:用户想要按段优先顺序排列7个序列:3,1,2。

正确的答案是

   SegmentID    SequenceID
    3           100
    3           200
    3           400
    3           430
    1           300
    1           410
    2           420

简而言之,我需要从上到下遍历记录集,随时抓取唯一序列并添加到列表中。

如何在TSql语句中执行此操作?

2 个答案:

答案 0 :(得分:1)

create table #data (SegmentID int,SequenceID int);

insert into #data values
(3,100),
(3,200),
(3,400),
(3,430),
(1,100),
(1,200),
(1,300),
(1,410),
(2,100),
(2,200),
(2,300),
(2,420);

此表声明了排序首选项:

create table #prefs (Preference int, SegmentID int);
insert into #prefs values(1,3),(2,1),(3,2);

with cte as
(   
    select #data.SegmentID,
        #data.SequenceID,
        Preference,
        row_number() over (partition by SequenceID order by Preference) rn
    from #data 
    inner join #prefs on #data.SegmentID = #prefs.SegmentID
)
select SegmentId,
    SequenceID
from cte
where rn = 1
order by Preference, SequenceID;

答案 1 :(得分:0)

样本: http://rextester.com/JKNKD15000

With cte (SegmentID, SequenceID) as 
(SELECT 3,           100 UNION ALL
SELECT 3,           200 UNION ALL
SELECT 3,           400 UNION ALL
SELECT 3,           430 UNION ALL
SELECT 1,           100 UNION ALL
SELECT 1,           200 UNION ALL
SELECT 1,           300 UNION ALL
SELECT 1,           410 UNION ALL
SELECT 2,           100 UNION ALL
SELECT 2,           200 UNION ALL
SELECT 2,           300 UNION ALL
SELECT 2,           420),
userOrder (SegmentID, orderID) as (
 SELECT 3, 1 UNION ALL
 SELECT 1, 2 UNION ALL
 SELECT 2, 3),
Results  (SegmentID, SequenceID, RN, orderID) as ( 
    Select A.*
         , Row_number() over (Partition by A.SequenceID order by B.orderID)  RN
         , B.orderID
from cte A
INNER JOIN userOrder B
  on A.SegmentID = B.SegmentID)

Select Top 7 * 
from results where RN = 1
order by OrderID, SequenceID