Выбрать случайную секционированную запись с указанным номером записи в каждом разделе - PullRequest
4 голосов
/ 26 декабря 2011

У нас есть таблица (с именем QuestionBank), в которой хранятся все вопросы:

Id     Topic     Hardness    Position
4        1          3           4
5        1          2           1
6        1          1           2
7        1          3           3
8        1          3           4
9        2          2           1
10       2          2           2
11       2          3           3
12       3          1           1
13       3          1           1
14       3          1           2

Каждый вопрос относится к теме и имеет свою твердость и позицию (каждый аналогичный вопрос по содержанию имеет одинаковую позицию в соответствующей теме).

Обратите внимание, что значение в столбце Позиция не имеет смысла, и оно просто разделяет похожие вопросы в теме.

Цель состоит в том, чтобы случайным образом выбрать N записей с X записями Harness = 1 и Y записями Hardness = 2 и Z записями Hardness = 3 и т. Д .; с этим ограничением, что в результирующем наборе, насколько это возможно, нет записей с похожей темой и положением.

Например, записи с Id = 4 и Id = 8 одинаковы в обеих темах и позициях, поэтому желательно, чтобы одна из них была в наборе результатов.

Ответы [ 2 ]

1 голос
/ 26 декабря 2011

Вот один из способов.

  1. Сначала, если любой Topic, Position имеет несколько вопросов, присвойте каждому из них случайный порядок RN1.
  2. Затем сортируйте это, но случайным образом внутри каждой группы. Все значения 1 для RN1, очевидно, будут упорядочены в первую очередь, прежде чем попасть на 2, который обозначает второй вопрос для конкретной комбинации Topic, Position.
  3. Затем используйте результат этого в вычислении ROW_NUMBER, разделенном на Hardness, чтобы упростить окончательный SELECT.

.

WITH T1
     AS (SELECT *,
                Row_number() OVER (PARTITION BY Topic, Position 
                                       ORDER BY Newid()) AS RN1
         FROM   QuestionBank),
     T2
     AS (SELECT *,
                Row_number() OVER (ORDER BY RN1, Newid()) AS RN2
         FROM   T1),
     T3
     AS (SELECT *,
                Row_number() OVER (PARTITION BY Hardness 
                                       ORDER BY RN2) AS RN3
         FROM   T2)
SELECT Id,
       Topic,
       Hardness,
       Position
FROM   T3
WHERE  ( Hardness = 1
         AND RN3 <= 3 )
        OR ( Hardness = 2
             AND RN3 <= 2 )
        OR ( Hardness = 3
             AND RN3 <= 2 )
ORDER  BY Topic,
          Position,
          Hardness 

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

0 голосов
/ 26 декабря 2011

Вы можете цикл WHILE, чтобы выбрать вопрос за один раз.

Чтобы выбрать случайный вопрос:

  1. выбрать все записи твердости 1 во временной таблице
  2. Используйте rand () , чтобы выбрать один из них
  3. Проверьте, был ли ранее выбран квестин с той же темой / позицией, если нет, то не был выбранвопросы и удалите его из выбора, сделанного в пункте 1.
  4. Выполняйте шаги 2–3, пока не будет задано N записей для твердости
  5. Выполните шаги 1–4 для других значений твердости.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...