我的查询有点与以下内容相同:
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
答案 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。