SQL Server子查询返回了多个值.当子查询遵循=,!=,<,<=,>,> =时,不允许这样做

Ani*_*mar 73 sql t-sql 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  
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

消息512,级别16,状态1,行2子查询返回的值超过1.当子查询跟随=,!=,<,<=,>,> =或子查询用作表达式时,不允许这样做.

有任何想法吗?

Jef*_*dge 44

试试这个:

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'
Run Code Online (Sandbox Code Playgroud)

除了cost列之外,这将返回多个相同的行.查看返回的不同成本值,并找出导致不同值的原因.然后向某人询问他们想要的成本值,并将标准添加到将选择该成本的查询中.


jk.*_*jk. 39

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

您可以修改查询以禁用然后启用触发器,如果您尝试运行的任何查询都不需要执行触发器.

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]
Run Code Online (Sandbox Code Playgroud)

  • 修复触发器而不是禁用触发器不是更好吗?这些触发器是出于某种原因创建的,不是吗?您可以通过禁用触发器来绕过一些重要功能...... (3认同)
  • @TT.是的,但请在答案中看到粗体文字.您可以修改查询以禁用然后启用触发器,如果​​您尝试运行的任何查询都不需要执行触发器. (2认同)

小智 21

SELECT COLUMN 
    FROM TABLE 
WHERE columns_name
    IN ( SELECT COLUMN FROM TABLE WHERE columns_name = 'value');
Run Code Online (Sandbox Code Playgroud)

注意:当我们使用子查询时,我们必须关注点

  1. 如果我们的子查询在这种情况下返回一个值,我们使用(=,!=,<>,<,> ....)
  2. 在这种情况下我们使用其他(多个值)(in,any,all,some)


May*_*ayo 13

cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier 
   where Supplier_Item.SKU=OrderDetails.Sku and 
      Supplier_Item.SupplierId=Supplier.SupplierID
Run Code Online (Sandbox Code Playgroud)

此子查询返回多个值,SQL正在抱怨,因为它无法在单个记录中为成本分配多个值.

一些想法:

  1. 修复数据,使现有子查询只返回1条记录
  2. 修复子查询,使其只返回一条记录
  3. 将top 1和order by添加到子查询中(DBA讨厌的令人讨厌的解决方案 - 但它"有效")
  4. 使用用户定义的函数将子查询的结果连接成单个字符串

  • 3; 所有**有能力的**开发者也应该讨厌这一点.有一段时间有关于"Pet Peeves"的问题; 我的意思是:"只是因为没有错误信息,并不意味着它'有效'!".也就是说,您可以添加#5:重组整个查询; 即不是获得客户和"查询"发票; 而是获得发票和"查找"客户. (5认同)

HLG*_*GEM 10

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

如果你只想要一个记录匹配,你可能需要在连接中获得一个派生表,以便在字段中获得你想要的值,如果你需要两个值,那么普通人join会这样做,但你会得到同一个id的多个记录在结果集中.如果你只想要一个,你需要决定哪一个,做的是,在代码中,你可以使用一个top 1order by,你可以使用max(),你可以使用min(),等等,这取决于数据的真正需求是什么.


egr*_*nin 10

要么您的数据不好,要么它的结构不符合您的想象.可能两者都有.

要证明/反驳此假设,请运行以下查询:

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
Run Code Online (Sandbox Code Playgroud)

如果这只返回几行,那么您的数据就不好了.如果它返回大量行,那么您的数据结构不会像您想象的那样.(如果它返回零行,我错了.)

我猜你有SKU多次包含相同的订单(两个单独的订单项,两个订单都相同SKU).


JAN*_*JAN 8

我有同样的问题,我使用in而不是=,从Northwind数据库示例:

查询是:查找1997年下订单的公司

试试这个 :

SELECT CompanyName
    FROM Customers
WHERE CustomerID IN (
                        SELECT CustomerID 
                            FROM Orders 
                        WHERE YEAR(OrderDate) = '1997'
                    );
Run Code Online (Sandbox Code Playgroud)

而不是:

SELECT CompanyName
    FROM Customers
WHERE CustomerID =
(
    SELECT CustomerID 
        FROM Orders 
    WHERE YEAR(OrderDate) = '1997'
);
Run Code Online (Sandbox Code Playgroud)


cjk*_*cjk 6

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