2010-06-05 4 views
0

мне нужна помощь оператора выбора в SQL Server/T-SQLНовая помощь с SQL Server выберите заявление

Моя таблица выглядит следующим образом:

Id (int) 
QuestionId (int) 
GenreId (int) 
QuestionScore (int) 

Я хочу, чтобы выбрать случайное N строки из эту таблицу, чтобы максимальное число одного и того же GenreId в результирующем наборе было меньше X для всех GenreId-s, кроме одного. Для этого GenreId мне нужно количество строк, чтобы GenreId был равен Y.

UPDATE
Я сделал этот запрос из предложений ниже, работает точно так же, как я хотел (для одного жанра, за исключением, но не тот, не проблема, пусть это будет так, плохо есть 2 запросов)

select top @N * from 
(select Id,GenreId,Rank() over (Partition BY GenreId order by newId()) as Rank,QuestionScore from Questions) t 
where t.Rank <= @X 
order by newId() 

Теперь мне нужно выбрать строки, чтобы средний QuestionScore находился между 1.7 и 2.3
как я могу это сделать? Мне нужны все столбцы, возвращенные в наборе результатов.
заранее спасибо :)

+2

Ваш запрос вообще кажется невозможным. Что, если N равно 100, X равно 5, а всего 2 жанра? Какие предположения вы делаете? И насколько случайным это должно быть? Это более важно, чтобы получить много разных жанров? Это нормально, если один жанр полностью не представлен в результатах. –

+1

Это поможет узнать версию SQL Server, которую вы используете. –

+0

Im using SQL Server 2005. Максимальное значение N равно 33, а количество жанров - ~ 50. Хорошо, если некоторые жанры не будут включены в результат. –

ответ

1

Для SQL Server 2005+, используйте:

SELECT TOP (@n) c.* 
    FROM (
SELECT a.id, 
     a.questionid, 
     a.genreid 
    FROM (SELECT t.*, 
       ROW_NUMBER() OVER (PARTITION BY t.genreid) AS rank 
      FROM TABLE t 
     WHERE t.genreid NOT IN (SELECT TOP 1 --ensure only one genre, see order by 
             t.genreid 
            FROM TABLE t 
           GROUP BY t.genreid 
           HAVING COUNT(*) = @y 
           ORDER BY t.genreid) 
    ) a 
WHERE a.rank < @x 
UNION ALL 
SELECT b.id, 
     b.questionid, 
     b.genreid 
    FROM TABLE b 
WHERE b.genreid IN (SELECT TOP 1 --ensure only one genre, see order by 
          t.genreid 
         FROM TABLE t 
        GROUP BY t.genreid 
        HAVING COUNT(*) = @y 
        ORDER BY t.genreid)) c 
+0

Я думаю, что @y - это другой предел для определенного жанра, он не должен использоваться для поиска жанра. Если бы это было так, он мог бы найти больше одного, что противоречило бы вопросу – Andomar

+0

@Andomar: OP утверждает, что у жанра, который исключен из набора, должно быть количество строк * y *. Очень вероятно, что может быть более одного жанра с * y * числом строк - TOP будет обрабатывать это, как только мы узнаем больше о том, какой из дубликатов будет выбран. –

+0

Спасибо большое :) –

0

В SQL Server, вы можете сделать это с вложенными подзапросов и top статей:

select top (@n) * 
from (
     -- Retrieve @y rows from the special genre 
     -- The prio field is used to ensure all these rows make it inside @n 
     select top (@y) 1 as prio, genreid, questionid 
     from @t 
     where genreid = @the_one 

     -- And up to @x rows per non-special genre 
     union all 
     select 2 as prio, genreid, questionid 
     from (
       select * 
       ,  row_number() over (partition by genreid 
              order by newid()) as rownr 
       from @t 
       where genreid <> @the_one 
       ) sub 
     where rownr < @x 
     ) sub2 
order by 
     prio, newid() 

Образец данных :

declare @t table (id int identity, QuestionId int, GenreId int) 

insert @t (GenreId, QuestionId) values 
    (1,1), 
    (2,1),(2,1), 
    (3,1),(3,1),(3,1), 
    (4,1),(4,1),(4,1),(4,1), 
    (5,1),(5,1),(5,1),(5,1),(5,1) 

declare @n int 
declare @x int 
declare @y int 
declare @the_one int 

set @n = 7 -- Total rows 
set @x = 3 -- With less then 3 per genre 
set @y = 3 -- Except three rows from genre @the_one 
set @the_one = 3 

Результаты (один экзамен) выходной сигнал отличается от каждого прогона:

prio genreid questionid 
1  3  1 
1  3  3 
1  3  2 
2  4  1 
2  1  1 
2  5  1 
2  5  4 
+0

Спасибо большое :) –

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