How is it possible that SQL query and ActiveRecord.find_by_sql return different results?

倾然丶 夕夏残阳落幕 提交于 2019-12-11 07:34:24

问题


I have a conundrum. I am writing a scope on my Account class that finds a bunch of account objects that meet a lengthy condition. Here is my scope:

 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)")
}

When I execute this scope by with Account.unverified_with_no_associations I receive this object back [#<Account:0x007f7fc94d79c0 id: nil>].

However when I connect to the database and execute the sql as is:

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);

I receive the number 221214. Why would it be that I get to differenct results? I've ruled out the possibility of connecting onto different databases. I've checked my .env files and have confirmed that I am in the same database as my application. Does anyone know why I would get such a difference in queries?

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

I discovered that find_by_sql does not like the inclusion of COUNT in its argument. When I remove the COUNT() from the sql and later execute a .count method I retrieve the matching number.

However, I still get different results when I use both methods.

What I really need are distinct accounts.id and accounts.email but the methods do not return the same output.

For example, when I execute the sql version I receive an output that looks like this:

row
---------
(1234,me@gmail.com)

but when I use the activerecord version I get this:

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

but with no accompanying email.

----UPDATE #3------

Also on my sql output I get this unknown OID 2249: failed to recognize type of 'row'. It will be treated as String. What does this mean?


回答1:


You have right result in both examples.

If you use only count in select you always got a number as result of query. So your result from database is expectable.

In rails case you trying to get some set of records by scope with count in select statement. It's expectable to got empty set if you have count in your query.

Try count_by_sql method http://apidock.com/rails/ActiveRecord/Base/count_by_sql/class to get number of records instead of empty set.

And use it without scope, but with class method:

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


来源:https://stackoverflow.com/questions/37816560/how-is-it-possible-that-sql-query-and-activerecord-find-by-sql-return-different

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!