SQL Server Subconsulta devuelve valor de más de 1. Esto no está permitido cuando la subconsulta sigue =,!=, <, <=,,>=


Corro la siguiente 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  

Obtengo el siguiente error:

Msg 512, Nivel 16, Estado 1, Línea 2 Subconsulta devolvió más de 1 valor. Esto no está permitido cuando la subconsulta sigue =,!=, , >= o cuando la subconsulta se usa como expresión.

¿Alguna idea?

Author: TT., 2010-04-16

10 answers

Prueba esto:

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'

Esto devolverá varias filas que son idénticas excepto para la columna cost. Mire los diferentes valores de costo que se devuelven y averigüe qué está causando los diferentes valores. Luego pregunte a alguien qué valor de costo quiere, y agregue los criterios a la consulta que seleccionará ese costo.

 34
Author: Jeffrey L Whitledge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 14:18:23

Compruebe si hay algún disparador en la tabla contra el que está intentando ejecutar consultas. A veces pueden lanzar este error al intentar ejecutar el disparador update/select/insert que está en la tabla.

Puede modificar su consulta para deshabilitar y luego habilitar el desencadenador si el desencadenador NO necesita ser ejecutado para cualquier consulta que esté tratando de ejecutar.

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]
 38
Author: jk.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-17 13:55:48
cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier 
   where Supplier_Item.SKU=OrderDetails.Sku and 
      Supplier_Item.SupplierId=Supplier.SupplierID

Esta subconsulta devuelve varios valores, SQL se queja porque no puede asignar varios valores a cost en un solo registro.

Algunas ideas:

  1. Corrige los datos de forma que la subconsulta existente devuelve solo 1 registro
  2. Corrige la subconsulta de forma que solo devuelve un registro
  3. Añadir un top 1 y ordenar por a la subconsulta (solución desagradable que odian los DBA - pero que "funciona")
  4. Utilice una función definida por el usuario para concatenar los resultados de la subconsulta en un cadena simple
 12
Author: Mayo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 13:24:13
select column 
from table 
where columns_name 
  in ( select column from table where columns_name = 'value');

Nota: cuando estamos usando sub-consulta debemos enfocarnos en el punto

  1. si nuestra sub consulta devuelve un valor en este caso estamos use (=,!=,,....)
  2. else (más de un valor ) en este caso estamos usando (in,any,all,some )
 12
Author: Diyar sereroy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-11 06:17:24

O tus datos son malos o no están estructurados de la forma en que crees que están. Posiblemente ambos.

Para probar/refutar esta hipótesis, ejecute 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

Si esto devuelve solo unas pocas filas, entonces sus datos son malos. Si devuelve lotes de filas, entonces sus datos no están estructurados de la manera en que cree que están. (Si devuelve cero filas, estoy equivocado.)

Supongo que tienes órdenes que contienen la misma SKU varias veces (dos líneas separadas, ambas ordenando lo mismo SKU).

 8
Author: egrunin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-17 19:15:12

Tuve el mismo problema , usé in en lugar de =, de la base de datos Northwind ejemplo:

La consulta es: Encontrar las empresas que realizaron pedidos en 1997

Prueba esto:

select CompanyName
from Customers
where CustomerID in (

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

En lugar de eso :

select CompanyName
from Customers
where CustomerID = (

            select  CustomerID 
            from Orders 
            where year(OrderDate) = '1997');
 8
Author: ron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-14 08:53:37

La solución es dejar de usar subconsultas correlacionadas y usar uniones en su lugar. Las subconsecuciones correlacionadas son esencialmente cursores, ya que hacen que la consulta se ejecute fila por fila y deben evitarse.

Es posible que necesite una tabla derivada en la combinación para obtener el valor que desea en el campo si solo desea que coincida un registro, si necesita ambos valores, entonces el join ordinario lo hará, pero obtendrá varios registros para el mismo id en el conjunto de resultados. Si solo quieres uno, tienes que decidir cuál y hacer eso en el código, se podría utilizar un top 1 con un order by, se podría utilizar max(), se podría utilizar min(), etc, dependiendo de lo que su requisito real para los datos es.

 8
Author: HLGEM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 11:29:38

La instrucción select en la parte cost de su select devuelve más de un valor. Necesita agregar más cláusulas where o usar una agregación.

 6
Author: cjk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 13:23:09

El error implica que esta subconsulta devuelve más de 1 fila:

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

Probablemente no desee incluir las tablas orderdetails y supplier en la subconsulta, porque desea hacer referencia a los valores seleccionados de esas tablas en la consulta externa. Así que creo que quieres que la subconsulta sea simplemente:

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

Sugiero leer sobre correlaciona vs no-subconsultas correlacionadas.

 4
Author: Dave Costa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 13:27:59

Como otros han sugerido, la mejor manera de hacer esto es usar una combinación en lugar de asignación de variables. Reescribiendo su consulta para usar una combinación (y usando la sintaxis de combinación explícita en lugar de la combinación implícita, que también se sugirió--y es la mejor práctica), obtendría algo como esto:

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' 
 3
Author: KP Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 14:15:24