5

ActiveRecord::Base サブクラスUserと tableがあると仮定すると、ActiveRecordusersでこのクエリを記述する方法がわかりません。

SELECT *
FROM (
    SELECT users.* 
    FROM   follows
    INNER JOIN users ON users.id = follows.following_id
    WHERE  username LIKE 'r%' AND follows.follower_id = 5717
    LIMIT 10

    UNION

    SELECT * 
    FROM   users 
    WHERE  username LIKE 'r%' 
    LIMIT 10
) AS users
LIMIT 10

カスタム生成テーブルから選択しています。このクエリを書き始めるにはどうすればよいでしょうか。これは可能ですか?もしそうなら、どのように、そうでなければ、私の代替手段は何ですか?

ありがとう!

4

4 に答える 4

0

Ifusers with username LIKE r%はレコードの小さなセットです。熱心な読み込みを使用します

users = User
        # get all users with matching username and all the associated follows
       .where("username LIKE 'r%' ").includes(:follows)
        # arrange the records in ruby  to get users with given follower id first
       .sort{|x|  x.follows.map(&:follower_id).include?(5717) ? 0 : 1 }
        # return first 10 records
       .first(10)

それ以外の場合は、ずらしたアプローチを使用します

# try to get 10 records with matching username and follower_id using an inner join
users  = User.joins(:follows).where("username LIKE 'r%' AND follows.follower_id = ?", 5717).group("users.id").limit(10)

# if less than 10 records found, run second query to get users with matching records only
users += User.where(" username LIKE 'r%' AND id NOT IN (?)", users.map(&:id)).limit(10-user.count) if users.count < 10

上記の両方の方法で、2 つの SQL クエリが作成されます。単一のクエリのオプションは、あなたのケースでは遅いと思われる外部結合を行うことです。

于 2013-09-19T06:41:36.617 に答える
0

このような複雑なクエリを実現するには、 find_by_sqlを使用できると思います

User.find_by_sql("SELECT * FROM (SELECT users.* FROM   follows INNER JOIN users ON users.id = follows.following_id WHERE  username LIKE 'r%' AND follows.follower_id = 5717 LIMIT 10 UNION SELECT * FROM   users WHERE  username LIKE 'r%' LIMIT 10) AS users LIMIT 10")
于 2013-09-19T08:06:35.880 に答える
0

ありがとう、それは興味深い質問です。

そのUNION実装に基づいて、これでうまくいくと思います:

# first sub query, inversed compared to your's, so that we get user fields
followed = User.group( 'users.id, users.username, follows.follower_id' ).having( "users.username like 'r%' and follows.follower_id = 5717" ).joins( :follows )

# second sub query
user = User.where( "username like 'r%'" )

# joining both using union
related_people_query = [ followed, user ].map { |query| query.select( 'users.id' ).to_sql }.join( ' UNION ' )
related_people = User.where( "users.id IN (#{related_people_query)" ).limit(10)

もちろん、これは大きなクエリであり、テストできませんでした。そのため、うまくいくかどうか知りたいです。

#joins編集:最初のサブクエリを忘れました

編集2:制限を忘れた

于 2013-09-18T14:21:16.003 に答える