当子查询可以为NULL时,SQL"IN子查询"

Soo*_*uNe 7 sql sqlite postgresql ruby-on-rails arel

我有一个查询需要返回子查询中不匹配的结果.子查询可以返回一个空结果,所以如果子查询返回一个空集来防止IN (NULL)哪个总是返回另一个NULL ,我需要设置一个默认值(比如说0).

例如

SELECT * FROM example_table WHERE id NOT IN (subquery_that_selects_ids)
Run Code Online (Sandbox Code Playgroud)

subquery_that_selects_ids 如果子查询找不到匹配的结果,则可以返回一组整数,即(1,2,5,6)或空集.

COALESCE 在这里不起作用,因为子查询可能会返回多个结果.

解决方案需要在SQLite或postgresql中工作.如何防止子查询返回空集?


每个人都在告诉我查询应该按照书面形式工作.你们都是正确的.该查询是由Rails3的AREL构建的,因为我在这里发布了完整的查询,我注意到AREL在使用数组条件时将NULL置于空集中.

IE我在rails中的查询看起来像:

Object.where("id NOT IN (?)", Object.where(other_conditions).select(:id))
Run Code Online (Sandbox Code Playgroud)

Object.where(other_conditions)评价为[]所述?正在取代NULL

所以我重新编写查询看起来像:

Object.where("id NOT IN (" + Object.where(other_conditions).select(:id).to_sql + ")")
Run Code Online (Sandbox Code Playgroud)

问题解决了.

我赞扬@Michael Buen,但也支持任何告诉我查询将按照书面形式工作的人,因为他们是正确的.特别感谢@OMG小马和@Ted Elliott!

Mic*_*uen 5

尝试:

SELECT * FROM example_table 
WHERE id NOT 
    IN (select x.id from subquery_that_selects_ids as x where x.id is not null)
Run Code Online (Sandbox Code Playgroud)

我认为你有点复杂,即使在子查询中没有行,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)
Run Code Online (Sandbox Code Playgroud)

UNION无论如何都会消除重复,UNION ALL会保留重复项