我正在两个表之间进行连接,并希望根据列是否有记录来选择列。我试图避免多个相同的字段,并试图将它们压缩成单列。类似的东西:
Select
id = (CASE WHEN a.id IS NULL THEN b.id ELSE a.id END),
name = (CASE WHEN a.name IS NULL THEN b.name ELSE a.name END)
From Table1 a
Left Join Table2 b
On a.id = b.id
Where a.id = @id
如果记录存在,我希望id
从Table1
填充,但如果不是从Table2
拉出来的话。之前的代码没有返回任何记录,因为NULL
中没有Table1
值,所以我的问题是如何运行检查以查看是否有任何记录存在?此外,如果有人知道一个更好的方法来完成我想要做的事情,我感谢指导和建设性的批评。
修改
看起来COALESCE
将适用于我正在努力完成的任务。我想提供一些关于我正在使用的更多信息,并就是否使用最佳方法获得一些建议。
我有一张臃肿的桌子Table2
,它正在制作中。我正在为这个系统构建新的Web应用程序,但不能证明完整的数据库重新设计是合理的,所以我试图“动态”做一个。我创建了一个新表Table1
,我正在编写以下方法的存储过程Get
(Select
),Set
(Update
),{{ 1}}(Add
),Insert
(Remove
)。这样,对于我的代码,似乎我正在处理一个没有膨胀的表。我的代码将简单地调用其中一个SP方法,然后存储过程将处理旧表和新表之间的数据。我目前正在处理Delete
方法,如果Get
中不存在,我需要检查旧表Table2
以获取记录。
感谢此处的建议,我的查询目前看起来像这样:
Table1
这适用于我正在努力实现的目标,如果有更好或更正确的方法可以解决这个问题,我想把它扔给有经验的人群提供任何提示或建议。
由于
答案 0 :(得分:1)
Select id = coalesce(a.id, b.id),
name = coalesce(a.name, b.name)
From Table2 b
Left Join Table1 a On a.id = b.id
Where b.id = @id
根据您的数据库平台,您可能需要使用ISNULL
或CASE
而不是COALESCE
。
答案 1 :(得分:1)
首先,您不需要案例陈述:
Select ISNULL(a.id,b.id) AS id, ISNULL(a.name,b.name) AS name,
From Table1 a
Left Join Table2 b
On a.id = b.id
Where a.id = @id
其次,如果我做对了,id
字段可以包含空值,在这种情况下你就搞砸了。我的意思是,ID是标识行的唯一值,如果它可以为null,则无法识别该行。
但是如果您想要的是从Table1和Table2获取记录并避免重复,那么简单的UNION
将正常工作,因为它会丢弃重复项:
select id, name
from Table1
where id = @id
union
select id, name
from Table2
where id = @id
答案 2 :(得分:1)
我怀疑你的问题可能来自左连接。再次尝试使用完整的外部联接,如下所示:
Select
id = coalesce(a.id, b.id),
name = coalesce(a.name, b.name)
From Table1 a
full outer Join Table2 b
On a.id = b.id
Where a.id = @id
答案 3 :(得分:0)
您可以执行以下操作:
从Table1 a中选择id,name,其中a.id不在(从Table2中选择id) 联盟 从表2 b
中选择id,name这将为您提供table1中没有table2中相应匹配的所有记录以及table2的所有记录。然后工会将结果合并。
答案 4 :(得分:0)
在第一个CASE语句中,a.id和b.id将始终为相同的值,但a.id具有值且b.id因LEFT JOIN而生成NULL值的实例除外。结果集中永远不会有一个NULL a.id值和一个非NULL b.id值。你可以在这个专栏中使用a.id.
对于第二个CASE语句,您可以在一个或两个表中找到带有值的名称列(当然,值可能不同)。你说你想“浓缩”这些列值;这个的SQL函数是COALESCE:
COALESCE(a.id, b.id)
返回第一个非NULL值(如果不是NULL则为a.id,否则为b.id)。它不会向你提示两个表中的不同名称。