嵌套的SQL语句产生意外的结果

时间:2017-05-15 14:12:10

标签: sql sql-server-2008 case

我正在尝试根据人们所属的级别提取注册信息。 00级中的人可以适合两个注册中的一个,所以我试图做一个嵌套的case语句。正如声明所说,我有很多人出现在嵌套案例陈述的两个结果中。所有其他级别工作正常。有没有人知道为什么结果会出现在when和else语句中,或者是否有更合适的方法来编写这个而不是嵌套的CASE语句?

CASE
        WHEN B.Level = '00' 
        THEN     
                CASE
                    WHEN C.SCREEN = '100' and C.FIELD_NUMBER = '65' and C.FIELD_VALUE = 'Y' THEN CONCAT(B.Location, ':', B.Level, ':', 'H')
                    ELSE CONCAT(B.Location, ':', B.Level, ':','A')
                END
            WHEN B.Level in ('A', 'B', 'C', 'D', 'E') THEN CONCAT(B.Location, ':', 'A-E')
            WHEN B.Level in ('F', 'G', 'H') THEN CONCAT(B.Location, ':', 'F-H')
            WHEN B.Level = 'I' THEN CONCAT(B.Location, ':', 'I')
            WHEN B.Level = 'J' THEN CONCAT(B.Location, ':', 'J')
            WHEN B.Level = 'K' THEN CONCAT(B.Location, ':', 'K')
            ELSE CONCAT(':', B.Location, B.Level) 
END AS Registration,

当前水平为00且符合Screen = 100,Field_Number = 65和Field _Value = Y标准的人的当前结果将导致重复,例如:

  • 人X位置1:等级1:H
  • 人X位置1:等级1:A

如果人X符合该标准,那么他们不应该出现第二个结果,或者至少这是我想要的结果。

1 个答案:

答案 0 :(得分:0)

case没有问题,问题出在join上。无论是对还是错,每个人复制的价值都超过一组。

如果您想测试case表达式对大量示例的效果,可以尝试以下方法:

-- Set up some test data:
declare @t table ([Level] nvarchar(10),Screen nvarchar(10), Field_Number nvarchar(10), Field_Value nvarchar(10), [Location] nvarchar(10));
insert into @t values('00','100','65','Y','Location1');

-- Generate 10 rows of the same values:
with t as
(
    select * from @t union all
    select * from @t union all
    select * from @t union all
    select * from @t union all
    select * from @t union all
    select * from @t union all
    select * from @t union all
    select * from @t union all
    select * from @t union all
    select * from @t
), tt as
(   -- And then join them together 6 times to get 1 million rows (10^6):
    select t1.* from t t1, t t2, t t3, t t4, t t5, t t6
)
select CASE
        WHEN B.Level = '00' 
        THEN     
                CASE
                    WHEN b.SCREEN = '100' and b.FIELD_NUMBER = '65' and b.FIELD_VALUE = 'Y' THEN CONCAT(B.Location, ':', B.Level, ':', 'H')
                    ELSE CONCAT(B.Location, ':', B.Level, ':','A')
                END
            WHEN B.Level in ('A', 'B', 'C', 'D', 'E') THEN CONCAT(B.Location, ':', 'A-E')
            WHEN B.Level in ('F', 'G', 'H') THEN CONCAT(B.Location, ':', 'F-H')
            WHEN B.Level = 'I' THEN CONCAT(B.Location, ':', 'I')
            WHEN B.Level = 'J' THEN CONCAT(B.Location, ':', 'J')
            WHEN B.Level = 'K' THEN CONCAT(B.Location, ':', 'K')
            ELSE CONCAT(':', B.Location, B.Level) 
        END AS Registration
    ,count(*) as c
from tt b
group by CASE
        WHEN B.Level = '00' 
        THEN     
                CASE
                    WHEN b.SCREEN = '100' and b.FIELD_NUMBER = '65' and b.FIELD_VALUE = 'Y' THEN CONCAT(B.Location, ':', B.Level, ':', 'H')
                    ELSE CONCAT(B.Location, ':', B.Level, ':','A')
                END
            WHEN B.Level in ('A', 'B', 'C', 'D', 'E') THEN CONCAT(B.Location, ':', 'A-E')
            WHEN B.Level in ('F', 'G', 'H') THEN CONCAT(B.Location, ':', 'F-H')
            WHEN B.Level = 'I' THEN CONCAT(B.Location, ':', 'I')
            WHEN B.Level = 'J' THEN CONCAT(B.Location, ':', 'J')
            WHEN B.Level = 'K' THEN CONCAT(B.Location, ':', 'K')
            ELSE CONCAT(':', B.Location, B.Level) 
    END

此语句的输出是100万Registration个完全相同的值:Location1:00:H。如果你真的想要,你可以让这个脚本返回任意数量的值,你的Registration不会改变。

要解决此问题,请在selectjoin表之间的B上执行C(我希望这些是描述性别名而不仅仅是A },BCD等?),已过滤Person X并查看返回的内容。我完全相信您会看到不同的数据组合。