1
votes

SQLITE: sélectionner dans la requête, les données de la sous-requête avec WHERE IN

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.


0 commentaires

3 Réponses :


2
votes

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


0 commentaires

2
votes

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.


3 commentaires

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



0
votes

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"


0 commentaires