SQL Server子查询返回多个值。这当子查询跟随不允许=,=,<, <= , >,> =

问题描述:

我运行下面的查询: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

尝试这个:

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列以外的多行相同的行。查看返回的不同成本值,并找出导致不同值的原因。然后询问他们想要的成本价值,并将标准添加到将选择该成本的查询中。

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

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

的错误意味着这个子查询返回超过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) 

我建议你阅读关联与不相关的子查询。

修复方法是停止使用相关子查询并使用连接。相关子查询本质上是游标,因为它们会导致查询逐行运行,应该避免。

如果您希望只有一条记录匹配,您可能需要连接中的派生表才能获得所需的值,如果您需要这两个值,那么普通join会这样做,但您会得到多个在结果集中记录相同的ID。如果你只需要一个,你需要决定哪一个在代码中,你可以使用top 1order by,你可以使用max(),你可以使用min()等,这取决于你对数据的真实需求是什么。

正如其他人所建议的,最好的方法是使用连接而不是变量赋值。重新写你的查询使用连接(使用显式连接语法,而不是隐含的加盟,这也表明 - 而且是最佳实践),你会得到这样的事情:

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' 

您的数据不好,或者它的结构不符合您的想法。可能都是。

为了证明/反驳这一假说,运行此查询:

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)的订单。

检查您试图执行查询的表上是否存在任何触发器。他们有时会在尝试运行表中的更新/选择/插入触发器时抛出此错误。

您可以修改您的查询以禁用,然后启用触发器,如果​​触发器不是需要为您试图运行的任何查询执行。

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

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

注:当我们使用子查询,我们必须集中指向

  1. 如果我们在这种情况下,子查询返回一个值,我们使用(=,=,<! >,<,> ....)在这种情况下
  2. 其他(多个值),我们使用(在,任何,所有,一些)

我有同样的问题,我用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');