Nous avons un tableau que nous utilisons pour stocker les réponses aux questions. Nous devons être en mesure de trouver des utilisateurs qui ont certaines réponses à des questions particulières. Donc, si notre tableau comprend les données suivantes:
user_id question_id answer_value
Sally 1 Pooch
Sally 2 Peach
John 1 Pooch
John 2 Duke
et nous voulons trouver des utilisateurs qui répondent «Pooch» pour la question 1 et «Peach» pour la question 2, le SQL suivant ne fonctionnera (évidemment) pas:
select user_id
from answers
where question_id=1
and answer_value = 'Pooch'
and question_id=2
and answer_value='Peach'
Ma première pensée a été de me joindre à la table pour chaque réponse que nous recherchons:
select a.user_id
from answers a, answers b
where a.user_id = b.user_id
and a.question_id=1
and a.answer_value = 'Pooch'
and b.question_id=2
and b.answer_value='Peach'
Cela fonctionne, mais comme nous autorisons un nombre arbitraire de filtres de recherche, nous devons trouver quelque chose de beaucoup plus efficace. Ma prochaine solution était quelque chose comme ceci:
select user_id, count(question_id)
from answers
where (
(question_id=2 and answer_value = 'Peach')
or (question_id=1 and answer_value = 'Pooch')
)
group by user_id
having count(question_id)>1
Cependant, nous voulons que les utilisateurs puissent répondre deux fois au même questionnaire, afin qu'ils puissent potentiellement avoir deux réponses à la question 1 dans le tableau des réponses.
Donc, maintenant je suis perdu. Quelle est la meilleure façon d'aborder cela? Merci!
la source
J'aime la méthode join, moi-même:
Mise à jour Après avoir testé avec une table plus grande (~ 1 million de lignes), cette méthode a pris beaucoup plus de temps que la
OR
méthode simple mentionnée dans la question d'origine.la source
Nous rejoignions le
user_id
de laanswers
table dans une chaîne de jointures pour obtenir des données d'autres tables, mais isoler le SQL de la table de réponses et l'écrire en termes si simples m'a aidé à trouver la solution:Nous utilisions inutilement une deuxième sous-requête.
la source
Si vous avez un grand ensemble de données, je ferais deux index:
Vous devrez vous joindre plusieurs fois en raison de la façon dont les données sont organisées. Si vous savez quelle valeur pour quelle question est la moins courante, vous pourrez peut-être accélérer un peu la requête, mais l'optimiseur devrait le faire pour vous.
Essayez la requête comme:
Le tableau a1 doit utiliser le premier index. Selon la distribution des données, l'optimiseur peut utiliser l'un ou l'autre des index. La requête entière doit être satisfaite à partir des index.
la source
Une façon de l'aborder est d'obtenir un sous-ensemble de user_id et de les tester pour la deuxième correspondance:
En utilisant la structure de Rolando:
Rendements:
la source