SQL Case 语句检查 NULL 和不存在的记录
我正在两个表之间进行联接,并希望根据列是否有记录来选择列。我试图避免拥有多个相同的字段,并尝试将它们压缩成单列。类似于:
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
如果记录存在,我希望从 Table1
填充 id
,但如果不存在,则从 Table2
提取。前面的代码没有返回任何记录,因为 Table1
中没有 NULL
值,所以我的问题是如何运行检查以查看是否存在任何记录?另外,如果有人知道更好的方法来完成我想做的事情,我很感激指导和建设性的批评。
编辑
看起来COALESCE
将适合我想要完成的任务。我想提供更多有关我正在使用的内容的信息,并就我是否使用最佳方法获得一些建议。
我有一个臃肿的表 Table2
并且它正在生产中。我正在为该系统构建新的 Web 应用程序,但无法证明整个数据库重新设计的合理性,因此我试图“即时”做一个。我创建了一个新表 Table1
,并且正在为以下方法 Get
(Select
)、Set
编写存储过程代码>(<代码>更新),<代码>添加(<代码>插入),<代码>删除(<代码>删除) 。这样,对于我的代码来说,我似乎正在使用一个不臃肿的表。我的代码将简单地调用 SP 方法之一,然后存储过程将处理旧表和新表之间的数据。我目前正在使用 Get
方法,如果 Table1
中不存在该记录,我需要检查旧表 Table2
中的记录。 感谢这里的建议,我的查询目前看起来像这样:
Select
id = coalesce(a.id, b.student_number),
first_name = coalesce(a.first_name, b.first_name),
last_name = coalesce(a.last_name, b.last_name),
//etc
From Table1 a
Full Outer Join Table2 b
On a.id = b.student_number
Where (a.id = @id Or b.student_number = @id)
这适用于我想要完成的任务,如果有更好或更正确的方法,我想将其扔给有经验的人群以获取任何提示或建议去做这件事吧。
谢谢
I am doing a join between two tables and want to select the columns based on whether they have a record or not. I'm trying to avoid having multiple of the same field and am trying to condense them into single columns. Something like:
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
I'd like id
to populate from Table1
if a record exists, but if not pull from Table2
. The previous code returns no records because there are no NULL
values in Table1
so my question is how do I run a check to see if any records even exist? Also if anyone knows of a better way to accomplish what I am trying to do I appreciate guidance and constructive criticism.
EDIT
It looks like COALESCE
will work for what I'm trying to accomplish. I'd like to give a little more info on exactly what I am working with and get some advice on whether I am using the best method.
I have a bloated table Table2
and it is in production. I'm working on building new web applications for this system but can't justify a complete database redesign so I am trying to do one "on the fly". I've created a new table Table1
and I am writing stored procedures for the following methods Get
(Select
), Set
(Update
), Add
(Insert
), Remove
(Delete
). This way, to my code, it will seem that I am working with a single table that is not bloated. My code will simply call one of the SP methods and then the stored procedure will handle the data between the old table and the new. I am currently working on the Get
method and I need to check the old table Table2
for a record if it doesn't exist in Table1
.
Thanks to the suggestions here my query currently looks like this:
Select
id = coalesce(a.id, b.student_number),
first_name = coalesce(a.first_name, b.first_name),
last_name = coalesce(a.last_name, b.last_name),
//etc
From Table1 a
Full Outer Join Table2 b
On a.id = b.student_number
Where (a.id = @id Or b.student_number = @id)
This works for what I'm trying to accomplish, I'd like to throw it out there to the experienced crowd for any tips or suggestions if there are better or more correct ways to go about this.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我怀疑您的问题可能来自于进行左连接。再次尝试使用完整外部联接,如下所示:
I suspect your problem may come from doing a left join. Try again using a full outer join, like this:
您可能需要使用
ISNULL
或CASE
而不是COALESCE
,具体取决于您的数据库平台。You may need to use
ISNULL
orCASE
instead ofCOALESCE
depending on your database platform.首先,您不需要 case 语句:
其次,如果我猜对了,
id
字段可以包含空值,在这种情况下您就完蛋了。我的意思是,ID 是标识一行的唯一值,如果它可以为空,则无法标识该行。但是,如果您想要从 Table1 和 Table2 中获取记录并避免重复,则简单的 UNION 就可以正常工作,因为它会丢弃重复项:
First, you don't need a case statement for that:
Second, if I get it right, the
id
field can contain nulls, and in that case you are screwed. I mean, the ID is a unique value that identify a row, if it can be null, you can't identify that row.But if what you want is getting records from Table1 and Table2 and avoid duplicates, a simple
UNION
will work fine, since it discards duplicates:你可以这样做:
select id, name from Table1 a where a.id not in (select id from Table2)
联盟
select id, name from Table2 b
这将为您提供 table1 中在 table2 中没有相应匹配项的所有记录以及 table2 的所有记录。然后工会将合并结果。
You could do something like:
select id, name from Table1 a where a.id not in (select id from Table2)
UNION
select id, name from Table2 b
This would give you all the records from table1 that didn't have a corresponding match in table2 plus all of table2's records. The union would then combine the results.
在第一个 CASE 语句中,a.id 和 b.id 将始终为相同的值,但 a.id 有值而 b.id 由于 LEFT JOIN 而生成 NULL 值的情况除外。结果集中永远不会存在具有 NULL a.id 值和非 NULL b.id 值的行。您可以对此列使用 a.id。
对于第二个 CASE 语句,您可能会在一个或两个表中找到带有值的名称列(当然,这些值可能不同)。您说您想“压缩”这些列值; SQL 函数是 COALESCE:
它返回第一个非 NULL 值(如果不是 NULL,则返回 a.id,否则返回 b.id)。它不会提示您两个表中的名称不同。
In your first CASE statement, a.id and b.id will always be same value, except for instances in which a.id has a value and b.id generates a NULL value because of the LEFT JOIN. There will never be a row in the result set with a NULL a.id value and a non-NULL b.id value. You could just use a.id for this column.
For the second CASE statement, you may find the name column in either or both tables with a value (and, of course, the values may be different). You said you want to "condense" the these column values; the SQL function for that is COALESCE:
which returns the first non-NULL value (a.id if it isn't NULL, otherwise b.id). It won't tip you off to different names in the two tables.