Подзапрос 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 значения. Это недопустимо, когда подзапрос следует =,! =, <, < =, > , >= или когда подзапрос используется как выражение.
Любые идеи?
Ответы
Ответ 1
Попробуйте следующее:
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'
Это приведет к возврату нескольких строк, которые идентичны, за исключением столбца cost
. Посмотрите на разные значения стоимости, которые возвращаются, и выясните, что вызывает разные значения. Затем спросите кого-нибудь, стоимость которого они хотят, и добавьте критерии к запросу, который выберет эту стоимость.
Ответ 2
Проверьте, нет ли каких-либо триггеров в таблице, с которой вы пытаетесь выполнить запросы. Иногда они могут вызывать эту ошибку, поскольку они пытаются запустить триггер 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]
Ответ 3
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 и сделайте заказ в подзапрос (неприятное решение, которое администраторы баз данных ненавидят, но оно "работает" ).
- Используйте определенную пользователем функцию для объединения результатов подзапроса в одну строку
Ответ 4
select column
from table
where columns_name
in ( select column from table where columns_name = 'value');
Примечание: когда мы используем подзапрос, мы должны сосредоточиться на точке
- Если наш вспомогательный запрос возвращает одно значение, в этом случае мы используем (=,! =, < > , <, > ....)
- else (более одного значения) в этом случае мы используем (in, any, all, some)
Ответ 5
Исправление состоит в том, чтобы прекратить использование коррелированных подзапросов и вместо этого использовать объединения. Корреляционные подзапросы являются, по существу, курсорами, поскольку они заставляют запрос запускать строки за строкой и их следует избегать.
Вам может понадобиться производная таблица в соединении, чтобы получить нужное значение в поле, если вы хотите, чтобы только одна запись соответствовала, если вам нужны оба значения, тогда обычный join
сделает это, но вы получите несколько записей для одного и того же идентификатора в наборе результатов. Если вам нужен только один, вам нужно решить, какой из них и сделать это в коде, вы можете использовать top 1
с order by
, вы могли бы использовать max()
, вы могли бы использовать min()
и т.д., В зависимости от какова ваша реальная потребность в данных.
Ответ 6
Оператор select в части затрат вашего выбора возвращает более одного значения. Вам нужно добавить дополнительные предложения или использовать агрегацию.
Ответ 7
Либо ваши данные плохие, либо они не структурированы так, как вы думаете. Возможно, оба.
Чтобы доказать/опровергнуть эту гипотезу, запустите этот запрос:
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
).
Ответ 8
У меня была та же проблема, я использовал in
вместо =
, из примера базы данных Northwind
:
Запрос: найдите компании, которые разместили заказы в 1997 году
Попробуйте следующее:
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');
Ответ 9
Ошибка подразумевает, что этот подзапрос возвращает более 1 строки:
(Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
Вероятно, вы не хотите включать в подзапрос таблицы orderdetails и поставщика, потому что вы хотите ссылаться на значения, выбранные из этих таблиц во внешнем запросе. Поэтому я думаю, что вы хотите, чтобы подзапрос был просто:
(Select Supplier_Item.Price from Supplier_Item where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
Я предлагаю вам ознакомиться с коррелированными и некоррелированными подзапросами.
Ответ 10
Как и другие, лучший способ сделать это - использовать соединение вместо назначения переменной. Повторная запись вашего запроса для использования соединения (и использование синтаксиса явного соединения вместо неявного соединения, которое также было предложено - и это лучшая практика), вы получили бы что-то вроде этого:
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'