Je lance la requête suivante:
SELECT
orderdetails.sku,
orderdetails.mf_item_number,
orderdetails.qty,
orderdetails.price,
supplier.supplierid,
supplier.suppliername,
supplier.dropshipfees,
cost = (SELECT supplier_item.price
FROM supplier_item,
orderdetails,
supplier
WHERE supplier_item.sku = orderdetails.sku
AND supplier_item.supplierid = supplier.supplierid)
FROM orderdetails,
supplier,
group_master
WHERE invoiceid = '339740'
AND orderdetails.mfr_id = supplier.supplierid
AND group_master.sku = orderdetails.sku
Je reçois l'erreur suivante:
Msg 512, Niveau 16, Etat 1, Ligne 2 La sous-requête a renvoyé plus de 1 valeur. Ceci n'est pas autorisé lorsque la sous-requête suit =,! =, <, <=,>,> = Ou lorsque la sous-requête est utilisée comme expression.
Des idées?
Essaye ça:
SELECT
od.Sku,
od.mf_item_number,
od.Qty,
od.Price,
s.SupplierId,
s.SupplierName,
s.DropShipFees,
si.Price as cost
FROM
OrderDetails od
INNER JOIN Supplier s on s.SupplierId = od.Mfr_ID
INNER JOIN Group_Master gm on gm.Sku = od.Sku
INNER JOIN Supplier_Item si on si.SKU = od.Sku and si.SupplierId = s.SupplierID
WHERE
od.invoiceid = '339740'
Cela renverra plusieurs lignes identiques, à l'exception de la colonne cost
. Examinez les différentes valeurs de coût renvoyées et déterminez la cause de ces différentes valeurs. Puis demandez à quelqu'un quelle valeur de coût ils veulent, et ajoutez les critères à la requête qui sélectionnera ce coût.
Vérifiez si la table sur laquelle vous essayez d'exécuter des requêtes contient des déclencheurs. Ils peuvent parfois émettre cette erreur alors qu’ils tentent d’exécuter le déclencheur update/select/insert qui se trouve sur la table.
Vous pouvez modifier votre requête pour la désactiver, puis l'activer si le déclencheur NE FAIT PAS doit être exécuté pour la requête que vous essayez d'exécuter.
ALTER TABLE your_table DISABLE TRIGGER [the_trigger_name]
UPDATE your_table
SET Gender = 'Female'
WHERE (Gender = 'Male')
ALTER TABLE your_table ENABLE TRIGGER [the_trigger_name]
SELECT COLUMN
FROM TABLE
WHERE columns_name
IN ( SELECT COLUMN FROM TABLE WHERE columns_name = 'value');
remarque: lorsque nous utilisons une sous-requête, nous devons nous concentrer sur le point
cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier
where Supplier_Item.SKU=OrderDetails.Sku and
Supplier_Item.SupplierId=Supplier.SupplierID
Cette sous-requête renvoie plusieurs valeurs. SQL se plaint car il ne peut pas affecter plusieurs valeurs au coût dans un seul enregistrement.
Quelques idées:
Le correctif consiste à arrêter d'utiliser des sous-requêtes corrélées et à utiliser des jointures à la place. Les sous-requêtes corrélées sont essentiellement des curseurs car elles entraînent l'exécution de la requête ligne par ligne et doivent donc être évitées.
Vous aurez peut-être besoin d'une table dérivée dans la jointure pour obtenir la valeur souhaitée dans le champ si vous souhaitez qu'un seul enregistrement corresponde. Si vous avez besoin des deux valeurs, l'ordinaire join
le fera, mais vous obtiendrez plusieurs enregistrements pour le même identifiant dans le jeu de résultats. Si vous n'en voulez qu'un, vous devez choisir lequel et le faire dans le code, vous pouvez utiliser un top 1
avec un order by
, vous pouvez utiliser max()
, vous pouvez utiliser min()
, etc., en fonction de vos besoins réels pour les données.
Soit vos données sont mauvaises, soit elles ne sont pas structurées comme vous le pensez. Peut-être les deux.
Pour prouver/réfuter cette hypothèse, exécutez cette requête:
SELECT * from
(
SELECT count(*) as c, Supplier_Item.SKU
FROM Supplier_Item
INNER JOIN orderdetails
ON Supplier_Item.sku = orderdetails.sku
INNER JOIN Supplier
ON Supplier_item.supplierID = Supplier.SupplierID
GROUP BY Supplier_Item.SKU
) x
WHERE c > 1
ORDER BY c DESC
Si cela ne renvoie que quelques lignes, alors vos données sont incorrectes . S'il renvoie beaucoup de lignes, alors vos données ne sont pas structurées comme vous le pensez. (si elles ne renvoient aucune ligne , je me trompe. )
J'imagine que vous avez des ordres contenant plusieurs fois le même SKU
(deux postes distincts, tous deux ordonnant le même SKU
).
J'ai eu le même problème, j'ai utilisé in
au lieu de =
, à partir de l'exemple de base de données Northwind
:
La requête est: trouver les sociétés qui ont passé des commandes en 1997
Essaye ça :
SELECT CompanyName
FROM Customers
WHERE CustomerID IN (
SELECT CustomerID
FROM Orders
WHERE YEAR(OrderDate) = '1997'
);
Au lieu de :
SELECT CompanyName
FROM Customers
WHERE CustomerID =
(
SELECT CustomerID
FROM Orders
WHERE YEAR(OrderDate) = '1997'
);
L'instruction select dans la partie des coûts de votre sélection renvoie plusieurs valeurs. Vous devez ajouter d'autres clauses Where ou utiliser une agrégation.
L'erreur implique que cette sous-requête renvoie plus d'une ligne:
(Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
Vous ne souhaitez probablement pas inclure les tables de détails de commande et de fournisseur dans la sous-requête, car vous souhaitez référencer les valeurs sélectionnées à partir de ces tables dans la requête externe. Je pense donc que vous voulez que la sous-requête soit simplement:
(Select Supplier_Item.Price from Supplier_Item where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
Je vous suggère de lire sur les sous-requêtes corrélées par rapport aux sous-requêtes non corrélées.
Comme d'autres l'ont suggéré, la meilleure façon de procéder consiste à utiliser une jointure au lieu d'une affectation de variable. Réécrivez votre requête pour utiliser une jointure (et en utilisant la syntaxe de jointure explicite au lieu de la jointure implicite, ce qui a également été suggéré - et constitue la meilleure pratique), vous obtiendrez quelque chose comme ceci:
select
OrderDetails.Sku,
OrderDetails.mf_item_number,
OrderDetails.Qty,
OrderDetails.Price,
Supplier.SupplierId,
Supplier.SupplierName,
Supplier.DropShipFees,
Supplier_Item.Price as cost
from
OrderDetails
join Supplier on OrderDetails.Mfr_ID = Supplier.SupplierId
join Group_Master on Group_Master.Sku = OrderDetails.Sku
join Supplier_Item on
Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID
where
invoiceid='339740'