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
您可以将原因代码返回到单独的列中,如下所示:
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以上是绝配.您可以根据自己的意愿定义原因,我的目的是让您了解如何使用案例进行此操作.