SQL查询和ActiveRecord.find_by_sql返回不同结果的可能性如何?

问题描述:

我有一个难题。我在我的Account类中编写了一个范围,该类找到了一堆满足冗长条件的帐户对象。这里是我的范围:SQL查询和ActiveRecord.find_by_sql返回不同结果的可能性如何?

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这个范围我收到这个对象返回[#<Account:0x007f7fc94d79c0 id: nil>]

然而,当我连接到数据库,并为是执行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文件,并确认我与我的应用程序位于同一个数据库中。有谁知道我为什么会在查询中获得这样的差异?

------------ -------- UPDATE

我发现find_by_sql不喜欢的COUNT在其参数纳入。当我从sql中删除COUNT()并稍后执行.count方法时,我检索匹配的数字。

但是,当我使用这两种方法时,我仍然得到不同的结果。

我真正需要的是不同的accounts.idaccounts.email但这些方法不会返回相同的输出。

例如,当我执行的SQL版本我收到的输出,看起来像这样:

row 
--------- 
(1234,[email protected]) 

但是当我使用ActiveRecord的版本,我得到这个:

[#<Account:0x007fdc9ec104d0 id: nil>] 

,但没有随邮件一起。

----更新#3 ------

而且在我的SQL输出我得到这个unknown OID 2249: failed to recognize type of 'row'. It will be treated as String.这是什么意思?

你在这两个例子中都有正确的结果。

如果您在select中仅使用count,则始终会收到一个作为查询结果的数字。所以你的数据库结果是可以预期的。

在rails案例中,您试图通过scopecount在select语句中获得一些记录集。如果您的查询中有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 
+0

rootatdarkstar,感谢您的回复。我不知道有一个'count_by_sql'方法。你会知道我在更新中指定的问题吗?我仍然没有匹配的记录。 –

+0

我会将您的答案标记为正确并打开一个新问题。感谢您对'count_by_sql'的帮助。 –

+0

无论如何,尽量使用你的sql代码*没有*范围。 – rootatdarkstar