SQL查询和ActiveRecord.find_by_sql如何返回不同的结果?
我有一个难题。 我在我的Account
类上编写了一个范围,它找到了一堆符合冗长条件的帐户对象。 这是我的范围:
scope :unverified_with_no_associations, -> { find_by_sql("SELECT COUNT(DISTINCT(accounts.id, accounts.email)) FROM accounts WHERE level = 0 AND id NOT IN (SELECT DISTINCT(account_id) FROM verifications) AND id NOT IN (SELECT DISTINCT(account_id) FROM positions) AND id NOT IN (SELECT DISTINCT(account_id) FROM edits) AND id NOT IN (SELECT DISTINCT(account_id) FROM posts) AND id NOT IN (SELECT DISTINCT(account_id) FROM reviews) AND id NOT IN (SELECT DISTINCT(sender_id) FROM kudos) AND id NOT IN (SELECT DISTINCT(account_id) FROM stacks WHERE account_id IS NOT NULL)") }
当我使用Account.unverified_with_no_associations
执行此范围时,我收到此对象[#]
。
但是当我连接到数据库并按原样执行sql时:
SELECT COUNT(DISTINCT(accounts.id, accounts.email)) FROM accounts WHERE level = 0 AND id NOT IN (SELECT DISTINCT(account_id) FROM verifications) AND id NOT IN (SELECT DISTINCT(account_id) FROM positions) AND id NOT IN (SELECT DISTINCT(account_id) FROM edits) AND id NOT IN (SELECT DISTINCT(account_id) FROM posts) AND id NOT IN (SELECT DISTINCT(account_id) FROM reviews) AND id NOT IN (SELECT DISTINCT(sender_id) FROM kudos) AND id NOT IN (SELECT DISTINCT(account_id) FROM stacks WHERE account_id IS NOT NULL);
我收到了号码221214
。 为什么我会得到不同的结果? 我已经排除了连接到不同数据库的可能性。 我检查了我的.env
文件并确认我和我的应用程序在同一个数据库中。 有谁知道为什么我会在查询中获得这样的差异?
———— ——–更新
我发现find_by_sql
不喜欢在其参数中包含COUNT
。 当我从sql中删除COUNT()
并稍后执行.count
方法时,我检索匹配的数字。
但是,当我使用这两种方法时,我仍会得到不同的结果。
我真正需要的是distinct accounts.id
和accounts.email
但这些方法不会返回相同的输出。
例如,当我执行sql版本时,我收到一个如下所示的输出:
row --------- (1234,me@gmail.com)
但是当我使用activerecord版本时,我得到了这个:
[#]
但没有随附的电子邮件。
—-更新#3 ——
另外在我的sql输出中,我得到了这个unknown OID 2249: failed to recognize type of 'row'. It will be treated as String.
unknown OID 2249: failed to recognize type of 'row'. It will be treated as String.
这是什么意思?
两个例子都有正确的结果。
如果你只使用count
in count
,你总是得到一个数字作为查询的结果。 所以你的数据库结果是可以预料的。
在rails情况下,您尝试按scope
获取一些记录,并在select语句中使用count
。 如果您在查询中有count
,则可以预期空集。
尝试使用count_by_sql
方法http://apidock.com/rails/ActiveRecord/Base/count_by_sql/class来获取记录数而不是空集。
并且使用它没有范围,但使用类方法:
def self.unverified_with_no_associations() self.count_by_sql("SELECT COUNT(DISTINCT(accounts.id, accounts.email)) FROM accounts WHERE level = 0 AND id NOT IN (SELECT DISTINCT(account_id) FROM verifications) AND id NOT IN (SELECT DISTINCT(account_id) FROM positions) AND id NOT IN (SELECT DISTINCT(account_id) FROM edits) AND id NOT IN (SELECT DISTINCT(account_id) FROM posts) AND id NOT IN (SELECT DISTINCT(account_id) FROM reviews) AND id NOT IN (SELECT DISTINCT(sender_id) FROM kudos) AND id NOT IN (SELECT DISTINCT(account_id) FROM stacks WHERE account_id IS NOT NULL)") end