Mat*_*mer 9 sql postgresql null ruby-on-rails
我在Rails3应用程序中遇到了意外的postgres查询问题.
我以为我会通过stackoverflow运行这个,看看互联网的大脑有什么要说:)
这个结果是预期的行为(以及为什么?!)或者这是一个错误?
鉴于我在Postgres 9.1.4数据库中有一个表Orders,
id state
===== ======
1 <-- nil (default value)
2 'success'
3 'failure'
Run Code Online (Sandbox Code Playgroud)
当我运行查询时:
Order.where('orders.state != ?', 'success').map { |order| order.id }
Order Load (3.8ms) SELECT "orders".* FROM "orders" WHERE (orders.state != 'success')
=> [3]
Run Code Online (Sandbox Code Playgroud)
我期待结果[1,3].显然有2行(!='成功')满足.
为什么这是nil!=''成功'在这里不正确?是!=只是忽略NULL值?应该是?
注意:我使用以下查询生成了所需的结果:
Order.where('orders.state IS NULL OR orders.state != ?', 'success').map { |order| order.id }
Order Load (2.3ms) SELECT "orders".* FROM "orders" WHERE (orders.state IS NULL OR orders.state != 'success')
=> [1, 3]
Run Code Online (Sandbox Code Playgroud)
任何意见将不胜感激.
mu *_*ort 11
PostgreSQL中有一个IS DISTINCT FROM比较运算符:
当任一输入为空时,普通比较运算符产生null(表示"未知"),而不是true或false.例如,
7 = NULL
产生null,就像7 <> NULL
.如果此行为不合适,请使用以下IS [ NOT ] DISTINCT FROM
构造:Run Code Online (Sandbox Code Playgroud)expression IS DISTINCT FROM expression expression IS NOT DISTINCT FROM expression
对于非空输入,
IS DISTINCT FROM
与<>
运算符相同.但是,如果两个输入都为null,则返回false,如果只有一个输入为null,则返回true.类似地,IS NOT DISTINCT FROM
与=
非null输入相同,但是当两个输入都为null时返回true,而当只有一个输入为null时返回false.因此,这些构造有效地表现为null是正常数据值,而不是"未知".
例如,给出您的样本数据:
=> select * from orders where state is distinct from 'success';
id | state
----+---------
1 |
3 | failure
(2 rows)
Run Code Online (Sandbox Code Playgroud)
所以你可以这样说:
Order.where('orders.state is distinct from ?', 'success').pluck(:id)
Run Code Online (Sandbox Code Playgroud)
请注意,我也切换到pluck
而不是你的map(&:id)
,将这个SQL发送到数据库:
select id from orders where orders.state is distinct from 'success'
Run Code Online (Sandbox Code Playgroud)
而不是select orders.* ...
使用客户端过滤器来提取id
s.