0

我得到了错误

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

在下面的查询中

select case
        when serial_number like ('550092%') then

             (select distinct  left(product, 6) from dbo.QS_WIP_Errors2 err
              where err.SERIAL_NUMBER = serial_number)
                --err.SERIAL_NUMBER in (SERIAL_NUMBER)) 

        else left(SERIAL_NUMBER,6) 

        end as Identnummer

from dbo.QS_defects def
 where INSPECT_TIME >= '2015-08-01' and INSPECT_TIME <= '2015-08-10'

(我也尝试了评论中的代码)我真的无法解释它,因为我认为通过选择一个不超过一行的不同值可以返回。我究竟做错了什么??

4

1 回答 1

0

如果serial_number您认为每个产品实际上是唯一的,那么即使是唯一的,您也得到不止一行的原因Serial_Number是因为您没有正确地为列添加别名。总之,你有:

SELECT  (   select distinct  left(product, 6) 
            from dbo.QS_WIP_Errors2 err
            where err.SERIAL_NUMBER = serial_number) -- NO ALIAS ON serial_number
FROM    dbo.QS_defects def

在您的相关子查询中,您对 的第二个引用没有别名serial_number,这意味着它是指外部表 ( def) 还是内部表 ( err) 是不明确的。在名称冲突的情况下,SQL Server 将假定您指的是内部表,因此您基本上有:

WHERE err.serial_number = err.serial_number

这当然会返回所有行,因为一切都等于自己。问题的快速演示:

DECLARE @T TABLE (ID INT, Name VARCHAR(20));
INSERT @T (ID, Name) VALUES (1, 'Test 1'), (2, 'Test 2');

SELECT  *
FROM    @T AS T1
        OUTER APPLY
        (   SELECT  CorrelatedName = Name
            FROM    @T AS T2
            WHERE   T2.ID = ID
        ) AS T3
WHERE   T1.ID = 1;

其输出显示“Test 1”和“Test 2”都作为相关名称返回:

ID  Name        CorrelatedName
----------------------------------
1   Test 1      Test 1
1   Test 1      Test 2

使用正确的别名,您只会得到一行:

DECLARE @T TABLE (ID INT, Name VARCHAR(20));
INSERT @T (ID, Name) VALUES (1, 'Test 1'), (2, 'Test 2');

SELECT  *
FROM    @T AS T1
        OUTER APPLY
        (   SELECT  CorrelatedName = Name
            FROM    @T AS T2
            WHERE   T2.ID = T1.ID
        ) AS T3
WHERE   T1.ID = 1;

ID  Name        CorrelatedName
----------------------------------
1   Test 1      Test 1

所以你的最终查询应该是:

SELECT  CASE WHEN def.serial_number LIKE '550092%' THEN
                (   SELECT  LEFT(err.Product, 6)
                    FROM    dbo.QS_WIP_Errors2 AS err
                    WHERE   err.serial_number = def.serial_number
                )
            ELSE LEFT(def.serial_number, 6)
        END AS IdentNumber
FROM    dbo.QS_defects AS def
WHERE   def.inspect_time >= '2015-08-01' 
AND     def.inspect_time <= '2015-08-10';

这需要更多的努力,但是当我编写查询时,我将限定所有内容1,这样就可以立即清楚每一列来自哪个表,并且这样的错误变得更容易发现。

1.如果是从一个表中简单选择,我可能不会为别名或限定列引用而烦恼,尽管即使那样我仍然尝试这样做,以防我以后需要添加表

于 2015-08-28T12:32:40.417 回答