PostgreSQL - только разные значения в полях - PullRequest
0 голосов
/ 25 июня 2018

У меня есть таблица с именем questions , содержащая один столбец, заполненный идентификаторами вопросов экзамена. Допустим,

Q1
Q2
Q2
...
Qn

Теперь я бы хотел выбрать все комбинации из трех вопросов, например:

1, 2, 3
...
2, 5, 6
4, 7, 1
...
9, 6, 8

И выделите их подмножество, состоящее из строк, которые имеют только глобально уникальные значения. В предыдущем случае:

1, 2, 3
9, 6, 8

Поскольку две другие записи содержат 2 и 1, обе содержатся в записи (1, 2, 3).

Как этого можно достичь в SQL? Цель состоит в том, чтобы создать, скажем, 8 экзаменов из вопросов, которые отличаются друг от друга.

Ответы [ 3 ]

0 голосов
/ 25 июня 2018

Тривиальный подход подобен этому (соединения CROSS будут медленными - например, для 100 вопросов может потребоваться полминуты)

  SELECT Q1.ID AS Q1, Q2.ID AS Q2, Q3.ID AS Q3
  FROM Questions AS Q1, Questions AS Q2, Questions AS Q3
  WHERE Q1.ID <> Q2.ID AND Q1.ID <> Q3.ID AND Q2.ID <> Q3.ID
  ORDER BY RANDOM() LIMIT 8

Однако есть более умные способы сделать это - этот ответ предназначен для MS SQL Server, но может быть адаптирован к PostgreSQL

0 голосов
/ 25 июня 2018

Дайте свои вопросы номерам: 1, 2, 3, 4, 5 ... n.Затем разделите на 3, отклонив остальные: 0, 0, 0, 1, 1, ... n / 3, чтобы получить группы по три.Вам решать, как нумеровать вопросы, например, по идентификатору (наименьший идентификатор - запись № 1, следующий идентификатор - запись № 2, ...) или случайным образом.Вот пример для случайного:

select *, (row_number() over (order by random()) - 1 ) / 3 as grp
from questions
order by grp;

Сохраните результат как есть или поверните его, чтобы получить одну строку на группу с тремя столбцами вместо этого, например,

select
  max(case when rn % 3 = 0 then q end) as q1,
  max(case when rn % 3 = 1 then q end) as q2,
  max(case when rn % 3 = 2 then q end) as q3
from 
(
  select *, row_number() over (order by random()) - 1 as rn
  from questions
) numbered
group by rn / 3
order by rn / 3;
0 голосов
/ 25 июня 2018

давайте рассмотрим таблицу вопросов, имеющую

Table : questions

Qid
1
2
3
.
n

Теперь, если вы хотите выбрать только 8 (из трех вопросов) различных рандомизированных подмножеств, тогда

SELECT FO,STRING_AGG(QID , ',') 
FROM (SELECT Qid , (Qid / 3) :: INT AS FO  FROM QUETIONS   
      ORDER BY RANDOM ()
      LIMIT 8*3 )
GROUP BY FO       
...