0
votes

Jointure externe gauche sans lignes en double

Après de nombreuses recherches, je n'ai pas pu résoudre mon problème. J'ai les tableaux suivants:

 entrez la description de l'image ici

Je souhaite sélectionner tous les enregistrements de ma table 'produit'. Mais j'ai un problème. J'ai reçu plusieurs lignes de la table 'product' lorsque j'exécute la requête suivante:

 SELECT dbo.product.id, dbo.product.name, dbo.product_price.value
              dbo.product_barcode.barcode

    FROM dbo.product LEFT OUTER JOIN
                      dbo.product_price ON dbo.product.id = dbo.product_price.product_id LEFT OUTER JOIN
                      dbo.product_barcode ON dbo.product.id = dbo.product_barcode.product_id 

                      WHERE  (dbo.product_price.id IN
                      (SELECT MIN(id) AS minPriceID
                       FROM      dbo.product_price AS product_price_1
                       GROUP BY product_id)) AND (dbo.product_barcode.id IN
                      (SELECT MIN(id) AS Expr1
                       FROM      dbo.product_barcode AS product_barcode_1
                       GROUP BY product_id))

Mon problème a été résolu avec la requête suivante:

  SELECT dbo.product.id, dbo.product.name, dbo.product_price.value
          dbo.product_barcode.barcode

FROM dbo.product LEFT OUTER JOIN
                  dbo.product_price ON dbo.product.id = dbo.product_price.product_id LEFT OUTER JOIN
                  dbo.product_barcode ON dbo.product.id = dbo.product_barcode.product_id 


3 commentaires

Veuillez fournir des exemples de données et les résultats souhaités. Si vous ne voulez que des lignes d'une table, pourquoi vous embêtez-vous à joindre quoi que ce soit?


Il semble que certains produits aient plus d'un prix ou code-barres. Si vous voulez seulement le "dernier", vous avez besoin d'un moyen de déterminer leur ordre. Notez que votre deuxième requête convertit les opérations de jointure externe en jointure interne car la clause where requiert les valeurs de droite -tables à main. Si vous modifiez la clause where pour autoriser les valeurs null , par exemple ou dbo.product_price.id est NULL , lorsqu'aucune ligne correspondante n'est trouvée, vous obtiendrez des résultats. Bien entendu, il n'y a aucune garantie que la valeur min soit celle que vous souhaitez.


Voir msdn pour la syntaxe de jointure externe gauche c # linq: docs.microsoft.com/en-us/dotnet/csharp/language-reference/...


3 Réponses :


0
votes

N'oubliez pas ce diagramme:

 entrez la description de l'image ici

Lorsque vous appelez LEFT JOIN et appliquez un filtrage comme dans le second image en haut à gauche, vous n'obtiendrez que les éléments appartenant à la table A .

Je souhaite sélectionner tous les enregistrements de ma table "produit". Mais j'ai un problème. J'ai reçu plusieurs lignes de la table 'product' lorsque j'exécute la requête suivante:

Pouvez-vous essayer d'appeler DISTINCT après SELECT , comme ceci:

SELECT DISTINCT dbo.product.id, dbo.product.name, dbo.product_price.value
          dbo.product_barcode.barcode
...


1 commentaires

@MohammadGh Je suis d'accord avec vous, mais cela dépend en fait à quel point vous êtes préoccupé par la performance. Si vous voulez une solution plus rapide que DISTINCT , vous pouvez utiliser GROUP BY à la place.



1
votes
 SELECT dbo.product.id, dbo.product.name, MIN(dbo.product_price.value),MIN(      dbo.product_barcode.barcode)
 FROM dbo.product 
 LEFT OUTER JOIN dbo.product_price ON dbo.product.id = dbo.product_price.product_id 
 LEFT OUTER JOIN dbo.product_barcode ON dbo.product.id = dbo.product_barcode.product_id 
GROUP BY dbo.product.id, dbo.product.name
While the above query should achieve your desired results  - one entry for product with the minimun product_price (if one exist) and minimum product_barcode (if one exist).I only assumed you wanted this based on the query you were writing. You need to spend more time thinking about the question you are trying to answer.Joining will multiply your results if more than one entry per join key is present in one of the tables.

0 commentaires

2
votes

Je pense que le problème est que les conditions sont dans la clause WHERE - essayez de déplacer les conditions de la clause WHERE vers chaque jointure:

SELECT dbo.product.id, dbo.product.name, dbo.product_price.value, 
dbo.product_barcode.barcode
FROM dbo.product
LEFT OUTER JOIN dbo.product_price ON dbo.product.id = dbo.product_price.product_id
  --moved from WHERE clause
  AND dbo.product_price.id IN (SELECT MIN(id) AS minPriceID FROM dbo.product_price AS product_price_1 GROUP BY product_id)
LEFT OUTER JOIN dbo.product_barcode ON dbo.product.id = dbo.product_barcode.product_id
  --moved from WHERE clause
  AND dbo.product_barcode.id IN (SELECT MIN(id) AS Expr1 FROM dbo.product_barcode AS product_barcode_1 GROUP BY product_id)


0 commentaires