我有一个查询需要返回在子查询中不匹配的结果。子查询可以返回一个空结果,所以如果子查询返回一个空集,我需要设置一个默认值(比如 0),以防止 IN (NULL)
总是返回另一个 NULL。
例如
SELECT * FROM example_table WHERE id NOT IN (subquery_that_selects_ids)
subquery_that_selects_ids
可以返回一组整数,即 (1,2,5,6)
如果子查询没有找到匹配的结果,则为空集。
COALESCE
在这里不起作用,因为子查询可能会返回多个结果。
解决方案需要在 SQLite 或 postgresql 中运行。 如何防止子查询返回空集?
每个人都告诉我查询应该像写的那样工作。你们都是对的。该查询由 Rails3 的 AREL 构建,当我要在这里发布完整的查询时,我注意到 AREL 在使用数组条件时将 NULL 放入空集。
即我在 Rails 中的查询如下所示:
Object.where("id NOT IN (?)", Object.where(other_conditions).select(:id))
当 Object.where(other_conditions)
评估为 []
时 ?
被替换为 NULL
所以我重写查询如下:
Object.where("id NOT IN (" + Object.where(other_conditions).select(:id).to_sql + ")")
问题已解决。
我赞扬@Michael Buen,但也赞成任何告诉我查询会按书面方式工作的人,因为他们是正确的。特别感谢@OMG Ponies 和@Ted Elliott!
最佳答案
尝试:
SELECT * FROM example_table
WHERE id NOT
IN (select x.id from subquery_that_selects_ids as x where x.id is not null)
我觉得你有点复杂,即使子查询中没有行,NOT IN 也会有行。您的查询无需修改即可运行。无论如何,如果你真的希望你的子查询产生行,即使条件不满足,使用 UNION
SELECT * FROM example_table
WHERE id NOT
IN (select x.id from subquery_that_selects_ids as x
where 1 = 0 -- empty set
union
select 0)
UNION 无论如何都会消除重复项,UNION ALL 会保留重复项
关于SQL "IN subquery"当子查询可以为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4486566/