2013-06-27 2 views
1

Les noms de table et de colonne sont vagues car je suis dans le secteur de la santé et je ne peux pas partager de détails spécifiques. J'utilise cette requête pour montrer le montant des économies réalisées à un client s'il achète un produit auprès de mon entreprise (tableau 1) au lieu de son fournisseur actuel (tableau 2).SQL Comparaison de 2 tables tout en limitant les données

J'ai 2 tables comme celui-ci sur un MSQL Server 2008:

Table 1

ProductID, Description, Vendor, Price


Table 2

ProductID, Description, Price

Je veux sélectionner chaque ligne de Table 2 et les données correspondantes de Table 1. Mais je veux seulement retourner le fournisseur avec le meilleur prix (le prix le plus bas parmi les fournisseurs) de Table 1, pas tous les fournisseurs. Donc pour tout ProductID dans Table 2 il devrait y avoir une correspondance de Table1, ou une valeur NULL s'il n'y a pas ProductID correspondant dans Table 1. J'ai joint les tables sur ProductID et j'ai renvoyé toutes les colonnes que je voulais, mais je ne peux pas l'obtenir pour limiter à un seul résultat du tableau 1. Si je fais cela avec 1000 lignes dans Table 2 je devrais retourner 1000 lignes. Je me suis terminé avec quelques extra des matchs de plusieurs fournisseurs.

Les résultats devraient ressembler à ceci:

T1.ProductID, T1.Description, Vendor, T1.Price, T2.ProductID, 
T2.Description, T2.Price, (T2.Price - T1.Price) as 'Amount Saved' 

SQL je l'ai écrit est assez simple:

SELECT 
    T1.ProductID, 
    T1.Description, 
    Vendor, 
    T1.Price, 
    T2.ProductID, 
    T2.Description, 
    T2.Price, 
    (T2.Price - T1.Price) AS 'Amount Saved' 

FROM 
    Table2 T2 LEFT OUTER JOIN Table1 T1 
     ON T2.ProductID = T1.ProductID 
ORDER BY T2.ProductID 

Cette réponse de D. Stanley travaillé; avec un changement mineur pour sélectionner chaque rangée avec le prix le plus bas.

SELECT 
    T1.ProductID, 
    T1.Description, 
    T1.Vendor, 
    T1.Price, 
    T2.ProductID, 
    T2.Description, 
    T2.Price, 
    (T1.Price - T2.Price) as 'Amount Saved' 
FROM Table2 T2 
LEFT JOIN (
    SELECT * FROM (
     SELECT ProductID, Description, Vendor, Price, 
     ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Price ASC) AS Row 
     FROM Table1) as result 
    WHERE row=1 
    ) AS T1 
    ON T2.ProductID = T1.ProductID 
+0

Pouvez-vous poster la question? –

+1

Qu'est-ce que "meilleur prix" voulez-vous dire prix le plus bas (minimum), maximum enregistré, etc.? s'il vous plaît coller le code que vous avez essayé –

Répondre

1

Vous pouvez utiliser ROW_NUMBER pour trouver la « meilleure » ligne correspondant de Table1:

SELECT 
    T1.ProductID, 
    T1.Description, 
    T1.Vendor, 
    T1.Price, 
    T2.ProductID, 
    T2.Description, 
    T2.Price, 
    (T1.Price - T2.Price) as 'Amount Saved' 
    FROM Table2 T2 
    LEFT JOIN (
     SELECT ProductID, Description, Vendor, Price, 
      ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Price DESC) Row 
      FROM Table1 
     ) T1 
     ON T2.ProductID = T1.ProductID 
0

Ce n'est pas clair, ce que vous voulez dire par "meilleur prix". Ajustez simplement la fonction MAX() à la fonction MIN() si ce n'est pas ce que vous voulez.

SELECT T1.ProductID, T1.Description, Vendor, T1.Price, T2.ProductID, 
T2.Description, T2.Price, (T1.Price - T2.Price) as 'Amount Saved' 
FROM (
SELECT 
ProductID, Vendor, Description, Price 
FROM Table1 t 
WHERE Price = (SELECT MAX(Price) FROM Table1 subT WHERE t.ProductID = subT.ProductID) 
) T1 RIGHT JOIN 
Table2 T2 ON T1.ProductID = T2.ProductID 
  • Here vous devriez lire de quelque chose.

EDIT: Je lis maintenant, que c'est pour SQL Server. La solution que j'ai fournie et le matériel de lecture supplémentaire fonctionnent également pour SQL Server. Bien que ce soit à partir du manuel MySQL, mais il y a juste le SQL standard impliqué.

0

Même pensé il y a quelques préformage meilleures possibilités de requête que j'aime cette façon, si vous voulez inclure toutes les possibilités avec min coût il suffit de supprimer la requête externe.Si je ne me trompe pas sur les noms des tables, faites-moi savoir ce que je suppose que vous étiez en demandant car je ne suis pas sûr à 100% de ce que vous entendez par "meilleur prix" mais je suppose qu'il était le plus bas basé sur votre champ "Montant enregistré" sélectionné.

SELECT 
    DISTINCT(T1.ProductId) AS ProductId, 
    Description, 
    Vendor, 
    Price, 
    SupplyDescription, 
    SupplyPrice, 
    AmountSaved AS 'Amount Saved' 
FROM 
(
    SELECT 
     T1.ProductId AS ProductId, 
     T1.Description, 
     T2.Vendor, 
     T1.Price, 
    /* T2.ProductId you are joining on this no need to include again*/ 
     T2.Description AS SupplyDescription, 
     T2.Price AS SupplyPrice , 
     (T1.Price - ISNULL(T2.Price,T1.Price)) as AmountSaved 
    FROM 
    Product T1 WITH(NOLOCK) 
    LEFT OUTER JOIN Supply T2 WITH(NOLOCK) 
     ON T1.ProductId = T2.ProductId 
    HAVING T2.Price = MIN(T2.Price) 
) tt 

REMARQUE: Cela suppose les tables des produits et d'approvisionnement ne sont pas mis à jour dynamiquement tout au long de la journée, ou changent très souvent, si ce n'est pas le cas (tableaux de produits et d'approvisionnement sont fréquemment mis à jour) et vous ne pourriez pas justifier les lectures sales produites en évitant le verrouillage juste enlever les WITH(NOLOCK) conseils de la requête

Questions connexes