也许我会发疯,或者只是需要休息一下,但在我的rails控制台Order.where(state: nil).count
中会返回1010
,但Order.where.not(state: "pending").count
会返回0
...如果是order的状态为nil,然后它不是“pending”,所以我希望not(state: "pending")
返回的集合包含集合where(state: nil)
。
这不是这样的吗?如果没有,是否会以不同的方式工作?
编辑:更多信息!当我去另一个数据库,其中一些记录的状态不是nil,我运行Order.where.not(state: "pending").count
我得到了一堆订单,其中没有一个是“待定”,但也没有一个是零。似乎where.not
隐含地在查询中添加了and not nil
?
# look into another shop, that has records
o = Order.where(shop_id: 2)
# summon dread spirits
t = Order.arel_table[:state]
o.where(t.eq(nil).or(t.eq("pending").not)).count
=> 1569
o.where(t.eq(nil)).count
=> 1471
所以在这种情况下,我得到的98条记录的状态既不是nil也不是“pending”,我得到状态为nil的所有记录。我真的很想知道为什么我不能只说where.not("pending")
并且具有相同的效果。如果有可能我可以调用的选项?比如,where.not("pending", include_nil: true)
?
编辑:根据@Filip Bartuzi的评论要求
Order.where.not(state: "pending").to_sql
=> "SELECT \"orders\".* FROM \"orders\" WHERE \"orders\".\"shop_id\" = 2 AND (\"orders\".\"state\" != 'pending')"
Orders.where(state: nil).to_sql
=> "SELECT \"orders\".* FROM \"orders\" WHERE \"orders\".\"shop_id\" = 2 AND \"orders\".\"state\" IS NULL"
答案 0 :(得分:5)
Order.where.not(state: "pending").to_sql
生成:
=> "SELECT \"orders\".* FROM \"orders\" WHERE \"orders\".\"shop_id\" = 2 AND (\"orders\".\"state\" != 'pending')"
它将返回VALUES中未处于“待定”状态的所有记录。当您将pending
设置为nil
时(如Order.first.update! state: nil
,它会在数据库中指定NULL
。
NULL
在SQL中不会被解释为值,因此它不会包含在SELECT
响应中
答案是:where.not(field: “something”)
不包含where(field: nil)
!
您可以在此处查看其工作原理:
http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
转到类别表并首先执行
UPDATE Categories
SET CategoryName = NULL
WHERE CategoryName = 'Beverages'
现在我们有了Count 8的类别,其中一个在NULL
列上有CategoryName
现在执行:
SELECT CategoryName FROM Categories
WHERE CategoryName != 'Condiments'
如您所见,返回了6条记录(因此它跳过了一条NULL
)
答案 1 :(得分:2)
SQL实现遵循3值逻辑,其中NULL不是值,但标记缺少值。 3值逻辑为逻辑运算定义了以下真值表:( null在这里是未知的)
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
由于where
测试数据集中每个条目的相等性(row.state == 'pending'
),如果row.state为NULL
,则通过上面的真值表得出结果为' Unknown& #39 ;. '未知'不是真的,所以行不包含在结果集中。
Wikipedia的更多信息。