2016-12-01 1 views
0

J'essaie de mieux comprendre SELECT IN. Serait-ce une requête valide?SQL SELECT IN retourne deux attributs

SELECT name 
FROM products 
WHERE product_id IN 
(SELECT product_id, SUM(unit_price) 
FROM sales 
GROUP BY product_id 
HAVING (SUM(unit_price) > 200)); 
+0

jetteront erreur 'Une seule expression peut être spécifiée dans la liste de sélection lorsque la sous-requête n'est pas introduit avec EXISTS.' –

Répondre

1

Non, pour la même raison pour laquelle ce ne serait pas un prédicat valide:

WHERE product_id = (1234, 16) 

Il n'a pas de sens de comparer qu'un scalaire est égal à un tuple.

Notez que SQL ne vous permet de comparer un tuple à tuple:

WHERE (product_id, 16) = (1234, 16) 

Mais le nombre d'éléments dans les deux tuples doivent être identiques.

Et vous pouvez également comparer une ligne à une sous-requête qui renvoie un tuple:

WHERE (product_id, 16) IN (SELECT product_id, SUM(unit_price) FROM ... 

Tant que les deux tuples ont le même nombre d'éléments.

0

Select l'intérieur In ne peut pas avoir 2 colonnes. Cela va jeter une erreur. Mais puisque vous êtes à la recherche de produits Ids vous ne avez pas besoin SUM(Unit_Price) de toute façon, la question ci-dessous devrait fonctionner parfaitement:

SELECT name FROM products WHERE product_id IN (SELECT product_id FROM sales GROUP BY product_id HAVING (SUM(unit_price) > 200)); 

Vous pouvez utiliser jointure interne et si vous voulez éviter IN partie.

+0

Cela dépend la base de données. Certains vous permettent certainement d'utiliser plusieurs colonnes, tant que le compte des deux côtés du 'in 'sont les mêmes. c'est-à-dire (colonne1, colonne2) dans (sélectionnez colonne3, colonne4 de some_table). – Allan

+0

Salut Srihari, merci pour votre aide! Je voudrais poser une question de suivi pour votre requête. Je suis un peu confus parce que je pensais que si j'incluais une clause HAVING alors le format du SELECT devrait être comme suit: SELECT nom_colonne, fonction_agrégée (nom_colonne) FROM nom_table WHERE nom_colonne valeur opérateur GROUP BY nom_colonne HAVING aggregate_function (column_name) valeur de l'opérateur; –

+0

Oui Hope Ashcraft, vous pouvez exécuter sans la fonction d'agrégation dans la clause select (atleast in oracle) –

0

Vous pouvez utiliser des expressions Tables communes (CTE) pour atteindre cet

;WITH CTE(ProductId, UnitPrice) 
AS(
SELECT product_id, SUM(unit_price) 
FROM sales 
GROUP BY product_id 
HAVING (SUM(unit_price) > 200)) 

SELECT [Name], c.UnitPrice 
FROM Products p INNER JOIN CTE c on p.Product_Id = c.ProductId