Есть ли способ чередовать порядок результата на основе одного идентификатора, сохраняя группировки на основе другого идентификатора в SQL?

#sql #postgresql #sql-order-by #union #window-functions

#sql #postgresql #sql-order-by #объединение #window-функции

Вопрос:

У меня есть этот запрос в Postgresql:

 (SELECT q.question, q.category_id, a.id, a.question_id, a.answer
    FROM questions q, answers a
    WHERE q.id = a.question_id
    AND category_id = 1
    AND question_id
    BETWEEN (SELECT property FROM users WHERE email = 'test@test.com')
    AND (SELECT property FROM users WHERE email = 'test@test.com')   14)
    
    UNION
    
(SELECT q.question, q.category_id, a.id, a.question_id, a.answer
    FROM questions q, answers a
    WHERE q.id = a.question_id
    AND category_id = 2
    AND question_id
    BETWEEN (SELECT laws FROM users WHERE email = 'test@test.com')
    AND (SELECT laws FROM users WHERE email = 'test@test.com')   16)
    
ORDER BY question_id, id
  

в настоящее время это возвращает результаты в этом формате:

  ----------------------------- ------------- ------------- -------- 
|          question           | category_id | question_id | answer |
 ----------------------------- ------------- ------------- -------- 
| What color is the sky?      |           1 |          16 | blue   |
| What color is the sky?      |           1 |          16 | green  |
| What color is the sky?      |           1 |          16 | purple |
| What color is the sky?      |           1 |          16 | red    |
| What color is a firetruck?  |           1 |          17 | orange |
| What color is a firetruck?  |           1 |          17 | teal   |
| What color is a firetruck?  |           1 |          17 | red    |
| What color is a firetruck?  |           1 |          17 | green  |
| What color is dirt?         |           2 |          18 | green  |
| What color is dirt?         |           2 |          18 | green  |
| What color is dirt?         |           2 |          18 | green  |
| What color is dirt?         |           2 |          18 | green  |
 ----------------------------- ------------- ------------- -------- 
  

Что я хочу сделать, это чередовать порядок на основе category_id, чтобы идентификатор категории чередовался следующим образом: 1,2,1,2 , но я хочу сохранить группы на основе question_id . Таким образом, результат будет выглядеть следующим образом:

  ----------------------------- ------------- ------------- -------- 
|          question           | category_id | question_id | answer |
 ----------------------------- ------------- ------------- -------- 
| What color is the sky?      |           1 |          16 | blue   |
| What color is the sky?      |           1 |          16 | green  |
| What color is the sky?      |           1 |          16 | purple |
| What color is the sky?      |           1 |          16 | red    |
| What color is dirt?         |           2 |          18 | green  |
| What color is dirt?         |           2 |          18 | green  |
| What color is dirt?         |           2 |          18 | green  |
| What color is dirt?         |           2 |          18 | green  |
| What color is a firetruck?  |           1 |          17 | orange |
| What color is a firetruck?  |           1 |          17 | teal   |
| What color is a firetruck?  |           1 |          17 | red    |
| What color is a firetruck?  |           1 |          17 | green  |
 ----------------------------- ------------- ------------- -------- 
  

Я пытался использовать ORDER BY row_number() OVER (PARTITION BY t.category_id ORDER BY t.category_id)
но это просто приводит к чередованию каждого из них без группировки по question_id

Ответ №1:

Я думаю, вам нужно следующее order by предложение:

 order by 
    rank() over(partition by category_id order by question_id),
    question_id,
    id
  

В основном это чередует категории / кортежи вопросов.

Примечания:

  • используйте стандартные, явные соединения ( from ... join ... on ), а не неявные соединения старой школы ( from ..., ... where ... ); это доисторический синтаксис, который не следует использовать в новом коде

  • весьма вероятно, что ваш запрос можно упростить, чтобы он не использовался union ; если бы вы задали другой вопрос с образцами данных и желаемыми результатами, можно было бы предложить