Subconsulta do SQL Server retornou mais de 1 valor. Isso não é permitido quando a subconsulta segue =,! =, <, ,> =

Eu corro a seguinte consulta:

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 

Estou tendo o erro a seguir:

Msg 512, nível 16, estado 1, linha 2 subconsulta retornou mais de 1 valor. Isso não é permitido quando a subconsulta segue =,! =, <, ,> = Ou quando a subconsulta é usada como uma expressão.

Alguma ideia?

Tente isto:

 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' 

Isso retornará várias linhas idênticas, exceto pela coluna de cost . Observe os diferentes valores de custo retornados e descubra o que está causando os diferentes valores. Em seguida, pergunte a alguém qual valor de custo ele deseja e adicione os critérios à consulta que selecionará esse custo.

Verifique se há algum gatilho na tabela na qual você está tentando executar consultas. Às vezes, eles podem lançar esse erro enquanto tentam executar o gatilho de atualização / seleção / inserção que está na tabela.

Você pode modificar sua consulta para desabilitar e habilitar o gatilho se o gatilho NÃO precisar ser executado para qualquer consulta que você esteja tentando executar.

 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'); 

observação: quando estamos usando a subconsulta, devemos nos concentrar para apontar

  1. Se a nossa subconsulta retornar um valor nesse caso, usaremos (=,! =, <>, < ,> ….)
  2. else (mais de um valor) neste caso estamos usando (em, any, all, some)
 cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID 

Essa subconsulta retorna vários valores, o SQL está reclamando porque não pode atribuir vários valores ao custo em um único registro.

Algumas ideias:

  1. Corrigir os dados de forma que a subconsulta existente retorne apenas 1 registro
  2. Corrigir a subconsulta de forma que ela retorne apenas um registro
  3. Adicione um top 1 e ordene até a subconsulta (solução desagradável que os DBAs odeiam – mas “funciona”)
  4. Use uma function definida pelo usuário para concatenar os resultados da subconsulta em uma única cadeia de caracteres

A correção é parar de usar subconsultas correlacionadas e usar junções. Subconsultas correlacionadas são basicamente cursores, pois fazem com que a consulta seja executada linha a linha e deve ser evitada.

Você pode precisar de uma tabela derivada na junit para obter o valor desejado no campo se quiser que apenas um registro corresponda, se você precisar dos dois valores, a join comum fará isso, mas você obterá vários registros para o mesmo id no conjunto de resultados. Se você quer apenas um, você precisa decidir qual deles e fazer isso no código, você poderia usar um top 1 com uma order by , você poderia usar max() , você poderia usar min() , etc, dependendo do que seu exigência real para os dados é.

Eu tive o mesmo problema, eu usei in vez de = , do exemplo de database Northwind :

Consulta é: Encontre as empresas que fizeram pedidos em 1997

Tente isto:

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

Ao invés disso :

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

Seus dados são ruins ou não estão estruturados como você pensa. Possivelmente ambos.

Para provar / refutar essa hipótese, execute esta consulta:

 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 isso retornar apenas algumas linhas, seus dados estarão ruins . Se ele retornar muitas linhas, seus dados não estarão estruturados como você pensa. (Se ele retorna zero linhas, eu estou errado. )

Suponho que você tenha pedidos contendo o mesmo SKU várias vezes (dois itens de linha separados, ambos solicitando o mesmo SKU ).

A instrução select na parte de custo de sua seleção está retornando mais de um valor. Você precisa adicionar mais cláusulas where ou usar uma agregação.

O erro implica que esta subconsulta está retornando mais de 1 linha:

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

Você provavelmente não deseja include os detalhes orderdetails e as tabelas do fornecedor na subconsulta, porque você deseja referenciar os valores selecionados dessas tabelas na consulta externa. Então eu acho que você quer que a subconsulta seja simples:

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

Eu sugiro que você leia subconsultas correlacionadas vs. não correlacionadas.

Como outros sugeriram, a melhor maneira de fazer isso é usar uma associação em vez de atribuição de variável. Reescrevendo sua consulta para usar uma junit (e usando a syntax de junit explícita em vez da junit implícita, que também foi sugerida – e é a melhor prática), você obteria algo assim:

 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'