2010-04-16 71 views
53

我運行下面的查詢:SQL Server子查詢返回多個值。這當子查詢跟隨不允許=,=,<, <= , >,> =

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, Level 16, State 1, Line 2 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

任何想法?

+24

哦,停止使用隱含的連接語法,這是一個非常糟糕的做法,難以維護,容易犯錯誤。 – HLGEM 2010-04-16 13:34:05

回答

28

嘗試這個:

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列以外的多行相同的行。查看返回的不同成本值,並找出導致不同值的原因。然後詢問他們想要的成本價值,並將標準添加到將選擇該成本的查詢中。

4

select中成本部分的select語句返回多個值。您需要添加更多where子句,或者使用聚合。

9
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和秩序子查詢(討厭的解決方案,數據庫管理員討厭 - 但它「作品」)
  4. 使用用戶定義函數來連接子查詢的結果爲一個字符串
+3

3;所有**主管**開發人員也應該討厭這一點。「Pet Peeves」後來有一個問題,我的意思是:「只是因爲沒有錯誤信息,並不意味着它」有效「!」也就是說,你可以添加#5:重構整個查詢;即不是獲取顧客和「查找」發票;而是獲得發票和「查找」客戶。 – 2010-04-16 13:59:53

2

的錯誤意味着這個子查詢返回超過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) 

我建議你閱讀關聯與不相關的子查詢。

5

修復方法是停止使用相關子查詢並使用連接。相關子查詢本質上是遊標,因爲它們會導致查詢逐行運行,應該避免。

如果您希望只有一條記錄匹配,您可能需要連接中的派生表才能獲得所需的值,如果您需要這兩個值,那麼普通join會這樣做,但您會得到多個在結果集中記錄相同的ID。如果你只需要一個,你需要決定哪一個在代碼中,你可以使用top 1order by,你可以使用max(),你可以使用min()等,這取決於你對數據的真實需求是什麼。

2

正如其他人所建議的,最好的方法是使用連接而不是變量賦值。重新寫你的查詢使用連接(使用顯式連接語法,而不是隱含的加盟,這也表明 - 而且是最佳實踐),你會得到這樣的事情:

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' 
4

您的數據不好,或者它的結構不符合您的想法。可能都是。

爲了證明/反駁這一假說,運行此查詢:

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)的訂單。

34

檢查您試圖執行查詢的表上是否存在任何觸發器。他們有時會在嘗試運行表中的更新/選擇/插入觸發器時拋出此錯誤。

您可以修改您的查詢以禁用,然後啓用觸發器,如果​​觸發器不是需要爲您試圖運行的任何查詢執行。

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] 
+1

修復觸發器而不是禁用觸發器會更好嗎?那些觸發器是有原因創建的,不是?您可以通過禁用觸發器來跳過一些重要的功能... – 2016-11-12 07:13:02

+0

@TT。是的,但請在答案中看到粗體文字。您可以修改您的查詢以禁用,然後啓用觸發器,如果​​觸發器不需要爲您嘗試運行的任何查詢執行。 – 2016-11-14 22:47:58

7
select column 
from table 
where columns_name 
    in (select column from table where columns_name = 'value'); 

注:當我們使用子查詢,我們必須集中指向

  1. 如果我們在這種情況下,子查詢返回一個值,我們使用(=,=,<! >,<,> ....)在這種情況下
  2. 其他(多個值),我們使用(在,任何,所有,一些)
4

我有同樣的問題,我用in代替=,從Northwind數據庫的例子:

Query is : Find the Companies that placed orders in 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'); 
相關問題