shouldn't `where.not(field: “something”)` include `where(field: nil)`?

你说的曾经没有我的故事 提交于 2019-12-05 19:26:58

Order.where.not(state: "pending").to_sql generates:

=> "SELECT \"orders\".* FROM \"orders\" WHERE \"orders\".\"shop_id\" = 2 AND (\"orders\".\"state\" != 'pending')"

It will return all records with VALUES which are not 'pending'. When u set pending to nil (like Order.first.update! state: nil it assigns NULL in database.

NULL isn't interpreted as value in SQL so it will not be included in SELECT response

So the answer is : where.not(field: “something”) does NOT include where(field: nil)!

You can check how it works here:

http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all

Go to the categories table and firstly execute

UPDATE Categories
SET CategoryName = NULL
WHERE CategoryName = 'Beverages'

So now we have Categories of Count 8 which one of them has NULL on column CategoryName

Now execute:

SELECT CategoryName FROM Categories
WHERE CategoryName != 'Condiments'

As you see 6 records where returned (so it skipped one with NULL)

SQL implementations follow 3 valued logic where NULL is not a value but marks the absence of a value. 3 valued logic defines the following truth table for logical operations: (null is Unknown here)

p       |q      |p OR q |p AND q|p = q
True    |True   |True   |True   |True
True    |False  |True   |False  |False
True    |Unknow |True   |Unknown|Unknown
False   |True   |True   |False  |False
False   |False  |False  |False  |True
False   |Unknown|Unknown|False  |Unknown
Unknown |True   |True   |Unknown|Unknown
Unknown |False  |Unknown|False  |Unknown
Unknown |Unknown|Unknown|Unknown|Unknown

Since where tests for equality (row.state == 'pending') on each entry in the data set, by the truth table above if row.state is NULL the result is 'Unknown'. 'Unknown' isn't true so the row isn't included in the result set.

More info at Wikipedia.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!