Subquery SQL Server ha restituito più di 1 valore. Questo non è permesso quando la subquery segue =,! =, <, ,> =

Eseguo la seguente query:

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 

Ottengo il seguente errore:

Il messaggio 512, livello 16, stato 1, riga 2 sottoquery ha restituito più di 1 valore. Questo non è permesso quando la subquery segue =,! =, <, ,> = O quando la sottoquery viene usata come espressione.

Qualche idea?

Prova questo:

 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' 

Ciò restituirà più righe identiche tranne la colonna di cost . Guarda i diversi valori di costo che vengono restituiti e scopri cosa sta causando i diversi valori. Quindi chiedi a qualcuno quale valore di costo vogliono e aggiungi i criteri alla query che selezionerà quel costo.

Controlla se ci sono trigger sulla tabella a cui stai cercando di eseguire query. A volte possono lanciare questo errore mentre stanno cercando di eseguire l’aggiornamento / select / insert trigger presente sulla tabella.

È ansible modificare la query per disabilitare quindi abilitare il trigger se il trigger NON deve essere eseguito per qualsiasi query si sta tentando di eseguire.

 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] 
 cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID 

Questa sottoquery restituisce più valori, SQL si lamenta perché non può assegnare più valori al costo in un singolo record.

Qualche idea:

  1. Correggere i dati in modo che la sottoquery esistente restituisca solo 1 record
  2. Correggere la sottoquery in modo che restituisca solo un record
  3. Aggiungi una top 1 e ordina alla sottoquery (soluzione sgradevole che i DBA odiano, ma “funziona”)
  4. Utilizzare una funzione definita dall’utente per concatenare i risultati della sottoquery in una singola stringa
 select column from table where columns_name in ( select column from table where columns_name = 'value'); 

nota: quando utilizziamo la sotto-query, dobbiamo concentrarci sul punto

  1. se la nostra query secondaria restituisce un valore in questo caso, usiamo (=,! =, <>, <,> ….)
  2. altrimenti (più di un valore) in questo caso usiamo (in, any, all, some)

O i tuoi dati sono cattivi o non sono strutturati come pensi tu sia. Forse entrambi.

Per dimostrare / confutare questa ipotesi, esegui questa query:

 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 

Se questo restituisce solo poche righe, allora i tuoi dati sono cattivi . Se restituisce molte righe, i tuoi dati non sono strutturati come pensi tu sia. (Se restituisce zero righe, ho sbagliato ) .

Immagino che tu abbia ordini contenenti la stessa SKU più volte (due elementi pubblicitari separati, entrambi che ordinano la stessa SKU ).

Ho avuto lo stesso problema, ho usato in invece di = , dall’esempio del database Northwind :

La domanda è: trova le aziende che hanno effettuato ordini nel 1997

Prova questo :

 select CompanyName from Customers where CustomerID in ( select CustomerID from Orders where year(OrderDate) = '1997'); 

Al posto di quello :

 select CompanyName from Customers where CustomerID = ( select CustomerID from Orders where year(OrderDate) = '1997'); 

La soluzione è quella di smettere di usare sottoquery correlate e usare invece i join. Le subquery correlate sono essenzialmente dei cursori poiché causano l’esecuzione riga per riga e dovrebbero essere evitate.

Potresti aver bisogno di una tabella derivata nel join per ottenere il valore desiderato nel campo se vuoi che corrisponda un solo record, se hai bisogno di entrambi i valori allora il join ordinario lo farà ma otterrai più record per lo stesso id nel set di risultati. Se ne vuoi solo uno, devi decidere quale e farlo nel codice, potresti usare un top 1 con un order by , potresti usare max() , potresti usare min() , ecc, a seconda di cosa il vero requisito per i dati è.

L’istruzione select nella parte di costo della selezione restituisce più di un valore. È necessario aggiungere più clausole where o utilizzare un’aggregazione.

L’errore implica che questa sottoquery restituisce più di 1 riga:

 (Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID ) 

Probabilmente non si desidera includere i record degli ordini e le tabelle dei fornitori nella sottoquery, perché si desidera fare riferimento ai valori selezionati da tali tabelle nella query esterna. Quindi penso che tu voglia che la sottoquery sia semplicemente:

 (Select Supplier_Item.Price from Supplier_Item where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID ) 

Ti suggerisco di leggere le subquery correlate e non correlate.

Come altri hanno suggerito, il modo migliore per farlo è utilizzare un join anziché l’assegnazione di variabili. Riscrivendo la tua query per usare un join (e usando la syntax del join esplicita invece del join implicito, che è stato anche suggerito – ed è la migliore pratica), otterresti qualcosa del genere:

 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'