Вложенный запрос SQL Server возвращает более 1 значения. Это запрещено, когда вложенный запрос следует после =,!=,


Я Запускаю следующий запрос:

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  

Я получаю следующее сообщение об ошибке:

Msg 512, Уровень 16, Состояние 1, Строка 2 Подзапрос вернул более 1 значение. Это запрещено, когда вложенный запрос следует после =, !=, , >= или когда подзапрос используется в качестве выражения.

какие идеи?

10 60

10 ответов:

попробуйте это:

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'

это вернет несколько строк, которые идентичны, за исключением

проверьте, есть ли какие-либо триггеры в таблице, к которой вы пытаетесь выполнить запросы. Иногда они могут вызвать эту ошибку, когда они пытаются запустить триггер update/select/insert, который находится в таблице.

вы можете изменить свой запрос, чтобы отключить, а затем включить триггер, если триггер НЕ необходимо выполнить для любого запроса, который вы пытаетесь запустить.

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

этот подзапрос возвращает несколько значений, SQL жалуется, потому что он не может назначить несколько значений стоимости в одной записи.

некоторые идеи:

  1. исправить данные таким образом, что существующий подзапрос возвращает только 1 запись
  2. исправьте подзапрос таким образом, что он возвращает только одну запись
  3. добавьте топ-1 и упорядочите по подзапросу (неприятное решение, которое ненавидят DBAs , но оно "работает")
  4. используйте определенную пользователем функцию для объедините результаты подзапроса в одну строку
select column 
from table 
where columns_name 
  in ( select column from table where columns_name = 'value');

Примечание: когда мы используем подзапрос, мы должны сосредоточиться на точке

  1. если наш подзапрос возвращает одно значение, в данном случае мы используем (=,!=,,....)
  2. else (более одного значения) в этом случае мы используем (in, any, all, some)

либо ваши данные плохие, либо они не структурированы так, как вы думаете. возможно и то и другое.

чтобы доказать / опровергнуть эту гипотезу, выполните следующий запрос:

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

Если это возвращает несколько строк, то ваши данные плохо. Если он возвращает много строк, то ваши данные не структурированы так, как вы думаете. (если он возвращает нулевые строки,я ошибаюсь.)

Я полагаю, что у вас есть заказы, содержащие то же самое SKU несколько раз (два отдельных элемента строки, оба заказа одного и того же SKU).

у меня была та же проблема , я использовал in вместо = С Northwind база данных пример :

запрос : найти компании, которые разместили заказы в

попробуйте это :

select CompanyName
from Customers
where CustomerID in (

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

вместо этого :

select CompanyName
from Customers
where CustomerID = (

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

исправление состоит в том, чтобы прекратить использование коррелированных подзапросов и использовать соединения вместо этого. Коррелированные подзапросы по существу являются курсорами, поскольку они заставляют запрос выполняться строка за строкой и их следует избегать.

вам может понадобиться производная таблица в соединении, чтобы получить значение, которое вы хотите в поле, если вы хотите, чтобы только одна запись соответствовала, если вам нужны оба значения, то обычный join будет делать это, но вы получите несколько записей с одинаковым ID в наборе результатов. Если вы хотите только один, вы нужно решить, какой из них и сделать это в коде, вы могли бы использовать top 1 С order by, вы могли бы использовать max(), вы могли бы использовать min(), etc, в зависимости от чего ваше реальное требование для данных.

оператор select в части затрат вашего select возвращает более одного значения. Вам нужно добавить больше предложений where или использовать агрегацию.

ошибка означает, что этот подзапрос возвращает более 1 строки:

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

вероятно, вы не хотите включать таблицы orderdetails и supplier в подзапрос, потому что вы хотите ссылаться на значения, выбранные из этих таблиц во внешнем запросе. Поэтому я думаю, что вы хотите, чтобы подзапрос был просто:

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

Я предлагаю вам прочитать на коррелированные и некоррелированные подзапросы.

как предлагали другие, лучший способ сделать это-использовать соединение вместо назначения переменной. Переписывая запрос на использование соединения (и используя явный синтаксис соединения вместо неявного соединения, которое также было предложено-и это лучшая практика), вы получите что-то вроде этого:

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'