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

时间:2016-06-14 15:42:35

标签: ruby-on-rails postgresql activerecord

我有一个难题。我正在我的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执行此范围时,我收到此对象[#<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,me@gmail.com)

但是当我使用activerecord版本时,我得到了这个:

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

但没有随附的电子邮件。

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

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

1 个答案:

答案 0 :(得分:1)

两个例子都有正确的结果。

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

在rails情况下,您尝试在scope中使用count在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