确定sql中不相等的特定字段

The*_*yan 2 sql t-sql sql-server-2008

我的查询有点等于以下内容:

SELECT @address = a.Id FROM dbo.[Address] AS a, dbo.Item as u
    WHERE a.Name = u.Name 
            AND ISNULL(a.Number, '') = ISNULL(u.Number, '') 
        AND ISNULL(a.Floor, '') = ISNULL(u.Floor, '')
        AND ISNULL(a.Door, '') = ISNULL(u.Door, '')
        AND a.Zip = u.Zip
        AND u.ItemId = @id;
Run Code Online (Sandbox Code Playgroud)

整个想法是从dbo.Address中找到与dbo.Item表对应的地址.

现在,问题是,从这个查询我需要有不匹配的,并确定他们不匹配的原因示例:我们找不到名称,数字,或地板等我一直在尝试通过使用连续的SELECT来完成此任务:

SELECT @addressId = a.Id FROM dbo.[Address] AS a, dbo.Item as u
        WHERE a.Name = u.Name 
            AND u.ItemId = @id;
        -- Name not found           
        IF @addressId IS NULL
        BEGIN
            SET @retval = 4
            RETURN @retval;
        END
        ELSE
        BEGIN
            SELECT @addressId = a.Id FROM dbo.[Address] AS a, dbo.Item as u
            WHERE a.Name = u.Name 
                AND a.Number = ISNULL(u.HusNr, '')
                AND u.ItemId = @id;
            -- Number not found
            IF @addressId IS NULL
            BEGIN
                SET @retval = 5
                RETURN @retval;
            END
... and so on
Run Code Online (Sandbox Code Playgroud)

但这很慢,我开始认为必须有一种更聪明的方法来实现这一目标.

注意(关于伊卡洛斯的回答):

这种方法的问题在于它尝试一次连接多个字段.Sql尝试连接所有字段,因此将为整行返回NULL,而不是特定列.如果我们想要特定的列,我们必须做类似的事情:

SELECT a.Id , 
       case when a.Name is null then 1
       when a.Number is null then 2
       when a.Floor is null and a.Door is null and a.Zip is null then 3
       when a.Number is not null and a. Floor is not null and a.Door is not null and a.Zip is not null then 0 end as Reason
FROM dbo.Item u1 left join dbo.[Address] a 
       ON a.Name = u1.Name left join dbo.Item u2
       ON a.Number = u2.Number left join dbo.Item u3
       ON a.Floor = u3.Floor left join dbo.Item u4
       ON a.Door = u4.Door left join dbo.Item u5
       ON a.Zip = u5.Zip
where  u.ItemId = @id;
Run Code Online (Sandbox Code Playgroud)

...但是我们得到了一堆我们不需要的结果,即所有可能的组合,这又是......我们不需要.如果我们使用上面CASE的那个,那么第一个总是正确的,因为第一个结果就是全部NULLs

Ica*_*rus 6

您可以将原因代码返回到单独的列中,如下所示:

SELECT a.Id , 
       case when a.Name is null then 1
       when a.Number is null then 2
       when a.Floor is null and a.Door is null and a.Zip is null then 3
       when a.Number is not null and a. Floor is not null and a.Door is not null and a.Zip is not null then 0 end as Reason
FROM dbo.[Address] a left join dbo.Item u
       on a.Name = u.Name 
       or a.Number = u.Number
       or a.Door = u.Door 
where  u.ItemId = @id;
Run Code Online (Sandbox Code Playgroud)

Reason 0以上是绝配.您可以根据自己的意愿定义原因,我的目的是让您了解如何使用案例进行此操作.