处理空值的最优雅方法是啥
Posted
技术标签:
【中文标题】处理空值的最优雅方法是啥【英文标题】:What's the most elegant way to deal with nulls处理空值的最优雅方法是什么 【发布时间】:2014-01-02 09:54:29 【问题描述】:我有两个表和一个如下所示的查询::
select * from table_1
where x.column_1 in (
select column_2 from table_2
where column_3 = 'foo')
这几乎对我有用; column_1
和 column_2
中有空值,我希望将其视为匹配项。
我可以用这个写一个union
:
-- query above
union all
select * from table_1
where column_2 is null
and exists (select * from table_2
where column_3 = 'foo'
and column_2 is null)
但是会扫描每个表两次,这似乎效率低下。
有没有办法将这两个查询结合起来进行高效查询?
【问题讨论】:
哪个 RDBMS,任何或特定实例? 【参考方案1】:试试这个
select * from table_1
where coalesce (column_1,'special value') in
(
select coalesce (column_2,'special value')
from table_2
where column_3 = 'foo'
)
当然'special value'
不应包含在table_2
的column_3
中,并且必须与列的数据类型兼容。
【讨论】:
如果数据中没有不能出现的'special value'
怎么办?
该死,我就知道会有人指出那个。思考。首先,我在最后一句话中缩小了我的想法。第二:您多久拥有可能(并且确实)包含所有可能值的可空列?但是,我添加了完整的解决方案。【参考方案2】:
这不适合你吗?
select *
from table_1 t1
where EXISTS (
select 1
from table_2 t2
where t2.column_3 = 'foo'
AND (
t1.column_1 = t2.column_2
OR (t1.column_1 IS NULL AND t2.column_2 IS NULL)
)
)
这将包括它们相等或都为 NULL 的地方。
我避免ISNULL, IFNULL, COALESCE
的原因是正如@alzaimar 所说,数据类型和特殊值 问题
编辑
正如@ypercube 所提到的,对于 mysql,这可以简化为
select *
from table_1 t1
where EXISTS (
select 1
from table_2 t2
where t2.column_3 = 'foo'
AND t1.column_1 <=> t2.column_2
)
【讨论】:
那是关联子查询,效率会很低 但它是 100% 正确的。我的尝试进行了全面扫描(我想),但它真的没有比这更无效的了。 您可以使用(mysql)<=>
operator 将条件简化为:AND t1.column_1 <=> t2.column_2
@Bohemian 这个查询会比你接受的那个更有效率。
@ypercube 你确定吗?不会对 table1 中的每一行执行一次内部查询?您是说优化器将其转换为联接?【参考方案3】:
试试这个
select T.* from table_1 T
LEFT JOIN table_2 S ON T.column_1 = S.column_2 OR NULLIF(T.column_1,NULL) = NULLIF(S.column_2 ,NULL)
where column_3 = 'foo'
【讨论】:
但是使用=
的空值不会匹配
@Bohemian 试试<=>
。【参考方案4】:
试试这个:
SELECT *
FROM table_1 t1
INNER JOIN table_2 t2
ON t1.column_1 = t2.column_2
WHERE t2.column_3 = 'foo'
AND t1.column_2 IS NULL
AND t2.column_2 IS NULL
【讨论】:
(错字:倒数第二行应该有 column_1。)这不起作用: 1. JOIN ON 将不包括 t1.column_1 或 t1.column_2 为空的行,那么 WHERE 将只过滤结果,丢失空匹配。 2. IS NULL 的 AND 必须是 ORed(不是 ANDed)。(每 1,进入 ON。) 3. 这从两个表返回 * 而不仅仅是 table_1。以上是关于处理空值的最优雅方法是啥的主要内容,如果未能解决你的问题,请参考以下文章
在 Silverlight 的 SaveFileDialog 中缺少 DefaultFileName 的最优雅的解决方法是啥?