Rails 5.2.2(活动记录)WITH语句

时间:2019-04-07 17:05:02

标签: sql postgresql activerecord

我正在使用Rails 5.2.2,并使用需要使用左外部联接创建的“ WITH”语句进行复杂的查询。

如何在活动记录中执行WITH语句?

我的TOTAL_PROFILES是由Query对象驱动的,并且会发生变化,而其余部分将始终保持不变。因此,基本上是想用WITH语句包装我的查询对象结果。

这是一个简化的SQL示例,希望有人可以引导我找到在Rails中完成此操作的最佳方法,因为我认为没有办法。我在TOTAL_PROFILE表上有一堆内部联接,但是在这里不显示它们。

WITH TOTAL_PROFILES
AS (
     SELECT profiles.*
           ,hobbies.*
     FROM profiles
     INNER JOIN 
                 "profiles" 
              ON "hobbies"."hobbyable_id"      = "profiles"."id" 
             AND "hobbies"."hobbyable_type"    = $1 
     WHERE (profiles.latitude  ( BETWEEN 42.055160808444576 
                               AND 42.19989259155542) )
)
, FAVORITE_FOR_USER
    AS (
        SELECT "favorites".* 
          FROM "favorites" 
         WHERE "favorites"."user_id"    = $1 
           AND "favorites"."profile_id" = $2 
         ORDER BY 
               "favorites"."id" ASC LIMIT $3 
       )    
SELECT F."user_id"
     , CASE 
            WHEN F."profile_id" IS NULL
            THEN 0
            ELSE 1
             END                          AS IS_FAVORITE_FOR_USER 
     , T.*           
  FROM 
       TOTAL_PROFILES     T
  LEFT JOIN
       FAVORITE_FOR_USER  F
    ON T."profile_id" = F."profile_id"

如何将其转换为ActiveRecord或Arel?

a_sql = ProfilesQuery::Search.call(:location => 'New York, NY').to_sql
params = []
params << User.first.id # 1
user_id_param = params.length

wrapper_query = <<~SQL
 SELECT F."user_id"
     , (F."profile_id" IS NOT NULL) AS IS_FAVORITE_FOR_USER
     , T.*
 FROM (#{a_sql}) T
 LEFT JOIN favorites F ON (F.profile_id = T.profile_id AND F."user_id" = $#{user_id_param})
SQL

conn = ActiveRecord::Base.connection.raw_connection
conn.prepare('my_query', wrapper_query )
result = conn.exec_prepared('my_query', ['1'])``

0 个答案:

没有答案