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

时间:2011-11-14 15:00:18

标签: sql sql-server-2008 tsql

我的查询有点与以下内容相同:

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;

整个想法是从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

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

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

这种方法的问题在于它尝试一次加入多个字段。 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;

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

2 个答案:

答案 0 :(得分: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;

上面的Reason 0完全匹配。您可以根据需要定义原因,我的目的是让您了解如何使用案例进行此操作。

答案 1 :(得分:0)

你有没有理由一次尝试这个地址?

通过在地址和项目之间使用LEFT OUTER连接,可以找到所有地址为空,这些连接为您的WHERE子句添加了Address = NULL。