2016-02-23 4 views
6

Vorrei un po 'di aiuto con questa query MySQL. Idealmente, lo genererei usando il node.js Sequelize ORM.MySQL join, ORDER BY RAND() quindi ordina ASC (preferibilmente usando Sequelize)

Le tabelle sono:

Questions: id, question 
Answers: id, question_id, answer 

Il mio codice Sequelize è:

models.questions.findAll({ 
    where: { 
    id: { 
     $notIn: not_in 
    } 
    }, 
    order: [['id','ASC'], [models.answers, 'id', 'ASC']], 
    attributes: ['id', 'question'], 
    include: [{ 
     model: models.answers, 
     attributes: ['id', 'question_id', 'answer'], 
    }] 
}) 

Con not_in insieme a -1, Sequelize genera questa query:

SELECT `questions`.`id`, 
     `questions`.`question`, 
     `answers`.`id`   AS `answers.id`, 
     `answers`.`question_id` AS `answers.question_id`, 
     `answers`.`answer`  AS `answers.answer` 
FROM `questions` AS `questions` 
     LEFT OUTER JOIN `answers` AS `answers` 
        ON `questions`.`id` = `answers`.`question_id` 
WHERE `questions`.`id` NOT IN (-1) 
ORDER BY `questions`.`id` ASC, 
      `answers`.`id` ASC 

e si traduce in:

id | question | answers.id | answers.question_id | answers.answer 
13 | first question | 17 | 13 | 1st answer 
13 | first question | 23 | 13 | 2nd answer 
13 | first question | 24 | 13 | 3rd answer 
14 | second question | 18 | 14 | 1st answer 
14 | second question | 21 | 14 | 2nd answer 
14 | second question | 22 | 14 | 3rd answer 
15 | third question | 19 | 15 | 1st answer 
15 | third question | 20 | 15 | 2nd answer 

Vorrei questo risultato, ma con la domanda ordinata in modo casuale.

Quindi invece di 13, 14 poi 15, potrebbe essere 14, 15, 13, ma con le risposte ancora allineate con la loro domanda e ordinate per answers.id.

Apprezzerebbero qualsiasi suggerimento per il codice Sequelize o la query MySQL per ottenere tale risultato. Grazie!

Ho provato ad aggiungere ORDER BY RAND() in vari punti ma alla fine mischiare le risposte pure.

P.S. Per inciso, in precedenza avevo bisogno di questo con una sola domanda scelto a caso, per il quale ho usato:

SELECT `questions`.`id`  AS `question_id`, 
     `questions`.`question` AS `question`, 
     `answers`.`id`   AS `answer_id`, 
     `answers`.`answer`  AS `answer` 
FROM (SELECT `questions`.`id`, 
       `questions`.`question` 
     FROM `questions` AS `questions` 
     WHERE (SELECT `question_id` 
       FROM `answers` AS `answers` 
       WHERE `questions`.`id` = `answers`.`question_id` 
         AND questions.id NOT IN (-1) 
       LIMIT 1) IS NOT NULL 
     ORDER BY RAND() 
     LIMIT 1) AS `questions` 
     INNER JOIN `answers` AS `answers` 
       ON `questions`.`id` = `answers`.`question_id` 
ORDER BY `answers`.`question_id`, 
      `answers`.`id` 

Il che sarebbe tornato, per esempio:

id | question | answers.id | answers.question_id | answers.answer 
14 | second question | 18 | 14 | 1st answer 
14 | second question | 21 | 14 | 2nd answer 
14 | second question | 22 | 14 | 3rd answer 
+0

Attualmente non possibile: è possibile utilizzare 'include.separate', che eseguirà due query separate https://github.com/sequelize/sequelize/issues/4875 –

risposta

1

In parole povere MySQL:

SELECT ... 
    FROM 
     (SELECT RAND() AS rnd, id FROM questions) AS r 
    JOIN questions AS q ON q.id = r.id 
    JOIN answers AS a ON a.question_id = q.id 
    ORDER BY r.rnd, a.id