MySQL Jointure Externe Gauche, à l'exclusion d'Éléments dans le Deuxième Tableau Appartenant à l'Utilisateur
J'ai deux tables dans ma base de données MySQL, l'un est une bibliothèque de tous les livres dans la base de données, et l'autre contenant des lignes correspondant à des livres qui sont dans une bibliothèque.
Par exemple:
Bibliothèque De Table
`id` `title`...
===== ===========
1 Moby Dick
2 Harry Potter
Collection Table
`id` `user` `book`
===== ====== =======
1 1 2
2 2 2
3 1 1
Ce que je veux faire est d'exécuter une requête qui affiche tous les livres qui sont pas dans une collection de l'utilisateur. Je peux exécuter cette requête pour afficher tous les livres qui ne sont pas dans tout collection de l'utilisateur:
SELECT *
FROM `library`
LEFT OUTER JOIN `collection` ON `library`.`id` = `collection`.`book`
WHERE `collection`.`book` IS NULL
Cela fonctionne bien dans la mesure où je peux dire. L'exécution de cette dans PHPMyAdmin entraînera dans tous les livres qui ne sont pas dans la collection de la table.
Cependant, comment puis-je limiter à un certain utilisateur? Par exemple, avec les données factices, je veux le livre 1 de résultat si l'utilisateur 2
exécute la requête, et pas de livres si l'utilisateur 1
exécute la requête.
Simplement l'ajout d'un AND user=[id]
ne fonctionne pas, et avec ma une connaissance très limitée de JOIN
déclarations, je ne suis pas vraiment n'importe où.
Aussi, l'ID de résultats retournés (de requête ci, ce qui ne veut pas faire ce que je veux, mais ne fonctionne pas) est 0-- comment puis-je m'assurer que l'ID retourné, c'est que de library.id
?
Oups-- je l'ai laissé comme article quand j'ai copié et collé. Il doit être "livre". J'ai changé la question.
OriginalL'auteur Andrew M | 2012-06-15
Vous devez vous connecter pour publier un commentaire.
Vous aurez pour affiner votre
LEFT JOIN
sélection de seulement les livres que par un utilisateur, puis tout ce qui estNULL
dans la table jointe sera rangées(livres) pour lequel l'utilisateur n'a pas dans sa collection:Une alternative est la suivante:
Cependant, la première solution est plus optimale que MySQL va exécuter la
NOT IN
sous-requête une fois pour chaque ligne plutôt qu'une seule fois pour la totalité de la requête. Intuitivement, vous vous en doutez MySQL pour exécuter la sous-requête une fois et l'utiliser comme une liste, mais MySQL n'est pas assez intelligent pour distinguer entre une corrélation et non sous-requêtes corrélées.Comme indiqué ici:
JOIN
trucs, pour quelque raison que ce soit, est difficile pour moi d'envelopper ma tête autour de la...Votre dernier paragraphe pointe vers un lien où
IN
les sous-requêtes sont mentionnés et pasNOT IN
les sous-requêtes. Donc, ce qu'on suppose, que les requêtes avecNOT IN
ne sont pas bien optimisé est faux. Voir cet excellent blog: PAS DANS vs n'EXISTE PAS vs LEFT JOIN / NULL: MySQLJe crois qu'il n'a pas d'importance si c'est
NOT IN
ouIN
. LeNOT
tout simplement l'inverse de la boolean retourné à partir deIN
. Article intéressant bien que +1L'article revendiqué que la course a pris la même quantité de temps. Je pense que c'est une optimisation de la spécifique à MySQL. Très probablement, il examine la requête à un niveau conceptuel et réaliser qu'il aurait pu être réécrit comme une jointure.
OriginalL'auteur Zane Bien
Comment à ce sujet? C'est juste à côté de ma tête - je n'ai pas accès à une base de données de test sur la droite maintenant. (désolé)
Merci pour votre aide de toute façon 😛 +1
Merci pour le +1. J'ai cruellement besoin de ces, être de nouveau ici :O)
OriginalL'auteur Joe Dyndale