7
votes

mysql Select / Supprimer à l'aide de Jointure sur quatre tables

J'ai quatre tables (dans [] sont des colonnes):

utilisateurs [id] code> p>

produits [id] p >

products [ID, valeur, utilisateur, produit] code> p>

commentaires [ID, produit, utilisateur] p>

P> P> P> Je voudrais sélectionner / et supprimer finalement des productrices où il n'y a pas de commentaire associé par le même utilisateur pour ce produit. C'est-à-dire que si l'utilisateur a noté le produit mais n'a pas commenté, cette note doit être supprimée. P>

Je pense que je pouvais atteindre cela en utilisant deux requêtes, d'abord: p>

    if $queryAbove==0 : DELETE FROM productRatings WHERE id=productRatings.id


0 commentaires

4 Réponses :


0
votes
  DELETE FROM productRatings WHERE id IN (SELECT pr.id FROM productRatings pr
      LEFT JOIN comments c on c.product = pr.product
      WHERE c.user = pr.user
      AND pr.comment IS NULL) 

4 commentaires

Cela n'accomplit pas ce que l'OP a demandé. Il souhaite supprimer une note de produit où aucun commentaire n'existe de l'utilisateur qui a créé la note de produit. Ne pas le garder si un commentaire existe


@pala_ merci! Je devais jeûner.


Cela échouerait probablement dans ce où id = avec une sélection imbriquée qui va fournir plus d'un résultat. Avec votre utilisation de est null devrait être probablement dans au lieu de =


@Bobnocrozz merci! J'ai changé ça.



1
votes

Vous devriez pouvoir simplement rejoindre les champs de la requête, puis vérifier si le commentaire est vide, comme ...

DELETE FROM `productRatings` 
JOIN `comments` ON (`productRatings`.`product` = `comments`.`product`)
WHERE `comments`.`comment_field` IS NULL
AND `productRatings`.`user_id` = ?;


3 commentaires

Je ne suis pas sûr que vous devez vous connecter à la table des utilisateurs car les commentaires et les tables de notation ont des identifiants utilisateur.


Je pense que cela échouera parce que c'est une jointure et vous n'avez pas précisé quelle table à supprimer.


Cela échouera pour plus de raisons que cela. rejoindre exécute un joint interne , ce qui signifie qu'il ne renvoie que des lignes correspondant, donc le est null partie du La clause est toujours fausse, donc même si elle était syntaxiquement correcte, elle ne supprimerait jamais rien.



2
votes
DELETE FROM `productRatings` WHERE productRatings.id NOT IN (
SELECT productRatings.id FROM `productRatings` JOIN `comments` ON productRatings.user = comments.user AND productRatings.product = comments.product )
I'd make copies of the tables in question and test that the above works on the test tables before using this on your production tables.Basically, the nested select will return all productRatings id's that the user who wrote the rating also made a comment on.  Using NOT IN, it will delete all ratings that the user who made the rating didn't also comment.As pala_ highlighted in the comments below, because this method uses nested sql, it will perform worse than a method that only uses joins on larger tables.

2 commentaires

Pour les grandes tables, cela effectuera pire qu'une version qui utilise uniquement des jointures.


@pala_ Yea, je vais ajouter ça à ma réponse. Votre réponse semble supérieure en ce sens qu'elle n'utilise pas de SQL imbriquée.



4
votes

Vous n'avez besoin que de la table de production et de commentaires - les travaux suivants: xxx

et il y a une démo ici: http://sqlfiddle.com/#!9/89575/1


1 commentaires

cela l'a fait, merci, cette jointure est vraiment simple quand vous savez ce que tu fais