我正在努力让自己围绕ActiveRecord查询。
我正在尝试在数据库中搜索ID为1..100,在其nil
字段中具有某些内容(而不是:website
且没有{{1 }}的true
字段中。
这是我希望工作的查询:
duplicate_domain
我还尝试了以下基本相同的查询变体:GolfRetailer.where.not(website: nil, duplicate_domain: true).where(id: 1..100)
但是,尽管肯定有满足这些要求的记录,但是两者都返回一个空数组。
当我运行GolfRetailer.where.not(website: nil).where(id: 1..100, duplicate_domain: !true)
时,我得到一个数组,而当我运行GolfRetailer.where.not(website: nil).where(id: 1..100)
时,我也得到了一个数组,但是所有 do 记录都具有真实的plicate_domain标志,这不是我想要的。
我宁愿不搜索具有GolfRetailer.where.not(website: nil, duplicate_domain: nil).where(id: 1..100)
的记录,因为这并不总是正确的(我可能尚未处理其域)。
为清楚起见,这是模型的架构。
duplicate_domain: nil
要使此查询有效,我缺少什么?
答案 0 :(得分:5)
之所以会这样,是因为在SQL中,当您执行!= TRUE
时,任何NULL
值都不会包含在结果中。这是因为NULL
值表示一个未知值,因此数据库不知道如何对未知值执行任何comparison operations,因此将其排除在外。>
解决此问题的一种方法是使用IS DISTINCT FROM
:
GolfRetailer
.where(id: 1..100)
.where.not(website: nil)
.where("duplicate_domain IS DISTINCT FROM ?", true)
正如其他人所提到的,您还应该问自己,是否真的不知道GolfRetailer
是否具有duplicate_domain
。
如果所有GolfRetailer
的{{1}}为duplicate_domain
实际上表示它们没有一个(NULL
),那么您应该考虑阻止{{1} }完全等于该列的值。
您可以通过在带有change_column
database migration的列上添加NOT NULL约束来做到这一点。
要添加NOT NULL约束,您首先需要确保该列中的所有数据都具有非null值。
false
如果您的应用程序处于负载状态,则还应注意此类迁移可能具有的潜在性能-特别是如果您添加具有默认值的NOT NULL约束。
考虑使用类似Strong Migrations的工具来帮助查找可能导致生产前停机的数据库迁移。