J'ai la requête suivante:
en_id, en_lect, en_main, en_opref, en_meros, en_family, en_header --------------------------------------- 123, ddd, 1, 0, 5, 123, 44 473, eee, 2, 0, 6, 473, 55
La table entriesSmallSplit
dans la sous-requête a une colonne appelée FirstLetter
. Je veux pouvoir renvoyer les données que FirstLetter
contient dans les résultats de la première requête SELECT en_lect, en_main, en_opref, en_id, en_meros, en_family, en_header
. La structure de la table entriesSmallSplit
:
en_tonismenosplit, en_family, FirstLetter, en_ref, en_se --------------------------------------- aaa, 123, g, 0, 0 bbb, 123, f, 0, 0 ccc, 321, f, 0, 0
entries
structure de la table
SELECT en_lect, en_main, en_opref, en_id, en_meros, en_family, en_header FROM entries WHERE en_id IN ( SELECT en_family FROM entriesSmallSplit WHERE (en_tonismenosplit = ?) AND (en_ref = 0) AND (en_se = 0) ) ORDER BY en_meros DESC, en_id DESC;
si l'utilisateur interroge aaa
je veux que le résultat soit:
ddd, 1, 0, 123, 5, 123, 44, g
(où g est dans le tableau entriesSmallSplit
)
est-ce possible, comment puis-je le faire de manière efficace?
Merci d'avance.
3 Réponses :
Au lieu d'une clause IN, vous pouvez utiliser une jointure interne
SELECT e.en_lect, e.en_main, e.en_opref, e.en_id, e.en_meros, e.en_family, e.en_header FROM entries e INNER JOIN entriesSmallSplit s ON s.en_family = e.en_id AND s.en_tonismenosplit = ? AND s.en_ref = 0 AND s.en_se = 0
et INNER JOIN est normalement plus efficace par rapport à la clause IN .. car une clause IN équivaut à plusieurs. INNER JOIN est une seule requête
Quelque chose comme:
SELECT en_lect, en_main, en_opref, en_id, en_meros, e.en_family, en_header, FirstLetter FROM entries AS e JOIN entriesSmallSplit AS ess ON en_id = ess.en_family WHERE en_tonismenosplit = ? AND en_ref = 0 AND en_se = 0 ORDER BY en_meros DESC, en_id DESC;
Pour plus d'efficacité, vous aurez besoin d'index sur les entrées (en_id)
et sur les entriesSmallSplit (en_tonimenosplit, en_ref , en_se, en_family)
. Celles-ci élimineront le besoin d'analyses complètes de la table; seules les lignes pertinentes des deux tableaux seront examinées et celles qui ne peuvent pas être renvoyées seront complètement ignorées.
Merci, vos réponses et scaisEdge sont toutes les deux les mêmes, je n'ai cliqué que sur la sienne comme acceptée, car c'est plus rapide (85 ms au lieu de 120 ms sur mon PC) en raison de la clause interne au lieu d'un simple JOIN.
@MirrorMirror Une fois que vous avez corrigé l'autre pour inclure la colonne FirstLetter
que vous vouliez, ils se compilent exactement avec le même bytecode. ( INNER JOIN
et JOIN
sont la même chose). C'est surtout une question de style et de préférence personnelle si vous mettez des filtres dans un WHERE
ou ON
; Je préfère le premier pour les choses qui ne lient pas explicitement les lignes des deux tableaux.
oui, je l'ai déjà réparé. Pour une raison quelconque, dans sqlite expert personal, c'est plus rapide, je ne sais pas pourquoi. Je vais probablement devoir voir le schéma pour voir pourquoi. Le vôtre est en fait plus lisible car il a le WHERE
Vous pouvez utiliser JOIN
pour implémenter cela.
SELECT e.en_lect, e.en_main, e.en_opref, e.en_id, e.en_meros, e.en_family, e.en_header, ess.FirstLetter FROM entries AS e INNER JOIN entriesSmallSplit AS ess ON e.en_family=ess.en_family WHERE ess.en_tonismenosplit="aaa"