2013-09-18 4 views
1

TABLEA:Выберите N количество строк и UNION результаты

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

Из приведенных выше данных нужно выбрать TOP N записей для particalar ConditionID и объединить его с другим набором лучших результатов N образуют различные условия Я бы.

Например: Для Состояние ID 10001 Выдают 2 Результаты и условия ID 10004 дают лучшие 3 результаты (оба этих результатов должны быть уникальными и не перекрывают друг друга):

Я мог бы сделать:

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

Но это всего лишь ограниченный сценарий, и запрошенные идентификаторы условия могут быть несколько, а не только 2 в приведенном выше сценарии.

Я не хочу, чтобы написать динамический SQL для повышения производительности, есть способ, которым я мог бы сделать нечто подобное с помощью ConditionId IN()

EDIT:

Результаты верхней 2 и top 3 не должен перекрывать содержимое, поэтому, если конкретный contentid уже был частью Query 1, он не должен быть частью следующего верхнего N и так далее.

+0

Что такое версию двигателя, которую вы используете? Sql Server 2000, 2005,? – saamorim

+0

Microsoft SQL Server 2008 –

+0

My Edit говорит «ContentIds» no ConditionIds –

ответ

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 
+0

Я внедрил EDIT на вопрос, не так ли? Благодаря ! –

+0

@ МуртазаМандви - я так думаю. Если я правильно понял ваше редактирование ... –

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

это то, что вы ожидали

+0

Это будет сделано, но оно не удовлетворяет динамическому аспекту множества условий, как упомянуто выше. –

+0

Выполнено ли это частично. Если да, укажите ввод через время выполнения. – Sudharsun

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 
+0

Будет ли это давать отчетливые результаты для ContentIds среди нескольких Conditionids? Извините, забыл упомянуть об этом в вопросе, сейчас редактируя. –

+0

См. Редактировать выше - Спасибо! –

Смежные вопросы