选择N行数并选择UNION结果

时间:2013-09-18 16:20:30

标签: sql-server-2008 tsql

TABLEA:

ConditionId ContentId
10004       101
10004       102
10001       104
10001       103
10001       115

根据以上数据,我需要为特定的ConditionID选择TOP N记录,并将其与另一组前N个结果合并,形成不同的条件id。

例如: 对于条件id 10001给出2个结果,条件ID 10004给出前3个结果(这两个结果应该是唯一的且不重叠):

我能做到:

SELECT top(2) * FROM TABLEA
WHERE Conditionid = 10001
UNION 
SELECT top(3) * FROM TABLEA
WHERE Conditionid = 10004

但这仅仅是一个有限的场景,在上述场景中,Ids请求的条件可能是多个,而不是2。

出于性能原因,我不想编写动态SQL,有没有办法通过使用ConditionId IN()来做类似的事情

编辑:

前2名和前3名的结果不应与竞争对手重叠,因此如果某个特定竞争者已经是查询1的一部分,则它不应该是下一个前N的一部分,依此类推。

3 个答案:

答案 0 :(得分:5)

单向(编辑以处理潜在的重复Conditionid)。

DECLARE @T TABLE
(
Conditionid INT,
Num INT
)

INSERT INTO @T 
VALUES(10001, 2),
      (10004, 3)


;WITH T(Conditionid, Num) AS
(
SELECT Conditionid,
       MAX(Num)
FROM @T 
GROUP BY Conditionid     
)
SELECT A.*
FROM  T
   CROSS APPLY (SELECT TOP (T.Num) *
                FROM   TABLEA A
                WHERE  A.Conditionid = T.Conditionid
                ORDER  BY A.ContentId) A 

答案 1 :(得分:3)

Sql-Server 2005及更高版本:

注意:在订购结果后应该记录最佳记录

declare table @t (numRecords int, id int)
insert into @t (numRecords, id)
values (2, 10001),
       (3, 10004)

;with cte as (
   select *, row_number() over (order by yourOrderCol) rn
   from yourTable
)
select cte.* 
from cte join @t t
     on cte.ConditionId = t.id and cte.rn <= t.numRecords
Order by cte.ConditionId

答案 2 :(得分:0)

SELECT top(2) * FROM TABLEA
WHERE Conditionid in ('10004', '10005')
UNION 
SELECT top(3) * FROM TABLEA
WHERE Conditionid = ('10004', '10006')

这是你所期望的