0

J'ai écrit la requête suivante qui est sortie de retour sans aucun message d'erreur mais je vois un problème avec la sortie:erreur avec le groupe par dans la requête interne de sous requête corrélative

select productid, productname, categoryid, unitprice 
FROM production.products as PP 
where unitprice in (select min(unitprice) as minprice 
        from production.products as PC 
        group by categoryid) 
order by categoryid 
go 

Résultat:

24 Product QOGNU 1 4.50 
3 Product IMEHJ 2 10.00 
19 Product XKXDO 3 9.20 
21 Product VJZZH 3 10.00 
33 Product ASTMN 4 2.50 
52 Product QSRXF 5 7.00 
54 Product QAQRL 6 7.45 
74 Product BKAZJ 7 10.00 
13 Product POXFU 8 6.00 

La sortie affiche plusieurs lignes pour categoryid = 3. Lorsque nous regroupons par categoryid, ne devrait-il pas afficher une seule ligne (un prix unitaire min) par categoryid.

Où vais-je mal? Merci d'avance à tous pour votre aide.

+0

Vous regroupez uniquement dans la sous-requête. Aussi votre 'IN' comparer avec tous les prix pas ceux sur la catégorie de produits. Vérifiez Tim réponse pour voir comment utiliser «JOIN» –

Répondre

0

Le problème avec votre requête actuelle est que la sous-requête de prix minimum est effectivement un pool de tous les prix minimum, pris dans chaque catégorie. Mais vous voulez vraiment limiter votre requête au prix minimum pour chaque catégorie respective. Une approche consiste à rejoindre à la place votre sous-requête, en limitant le jeu de résultats comme vous le souhaitez.

SELECT 
    PP.productid, 
    PP.productname, 
    PP.categoryid, 
    PP.unitprice 
FROM production.products AS PP 
INNER JOIN 
(
    SELECT categoryid, MIN(unitprice) AS minprice 
    FROM production.products 
    GROUP BY categoryid 
) t 
    ON PP.categoryid = t.categoryid AND 
     PP.unitprice = t.minprice 
ORDER BY categoryid 
+0

Merci à tous. Maintenant, je sais où je me suis trompé. Vos réponses ont été très utiles! –

+0

@NikhilaBakurupanda Est-ce que la bonne correction est possible? –

1

Votre requête n'est pas corrélée. Vous semblez avoir l'intention:

select productid, productname, categoryid, unitprice 
FROM production.products p 
where p.unitprice = (select min(p2.unitprice) as minprice 
        from production.products p2 
        where p2.categoryid = p.categoryid 
        ) 
order by p.categoryid; 

Un group by ne fait pas le sous-requête corrélée. Un where (bon, parfois on aussi) est nécessaire.

Votre requête spécifique présente un problème de logique. Il obtient n'importe quel produit dont le prix est le prix minimum de n'importe quelle catégorie - même pas le sien.

Je voudrais écrire cela comme:

select p.productid, p.productname, p.categoryid, p.unitprice 
from (select p.*, 
      min(p.price) over (partition by p.categoryid) as minprice 
     from production.products p 
    ) p 
where p.price = p.minprice 
order by p.categoryid; 

Note: Si plusieurs produits ont tous le même prix minimum, cela retourne tous. Si vous voulez spécifiquement un, puis utilisez row_number():

select p.productid, p.productname, p.categoryid, p.unitprice 
from (select p.*, 
      row_number() over (partition by p.categoryid order by p.price asc) as seqnum 
     from production.products p 
    ) p 
where seqnum = 1 
order by p.categoryid; 
0

Est-ce que vous voulez obtenir le prix unitaire min pour chaque catégorie?

SELECT * FROM (
    SELECT productid, productname, categoryid, unitprice,ROW_NUMBER()OVER(PARTITION BY categoryid ORDER BY unitprice) AS ln 
    FROM production.products as PP 
) AS t WHERE t.ln=1 
order by categoryid