【问题标题】:Joining 2 different tables where user_id equals to and created_at between 2 dates连接 2 个不同的表,其中 user_id 等于和 created_at 在 2 个日期之间
【发布时间】:2020-02-04 18:50:18
【问题描述】:

在我的应用程序中,我有 3 个模型 UserVisitPost。我想要实现的是选择属于uservisitsposts,其中created_at 介于2 个日期之间,group 它们由day (我是将groupdate 用于group_by_day) 并在visitsposts 上返回一个count 用于该捐赠日。

我尝试了几次都没有运气:

User.joins(:visits,:posts).where("visits.user_id = ?, posts.user_id = ?", current_user.id, current_user.id)
    .where("visits.created_at >= ? AND visits.created_at <= ?", 15.days.ago.midnight.in_time_zone("Berlin"), 2.days.ago.midnight.in_time_zone("Berlin"))
    .where("posts.created_at >= ? AND posts.created_at <= ?", 15.days.ago.midnight.in_time_zone("Berlin"), 2.days.ago.midnight.in_time_zone("Berlin"))
    .group_by_day(:created_at, range: 15.days.ago.midnight.in_time_zone("Berlin")..Time.now.in_time_zone("Berlin"), format: "%d %b")
    .count

这给了我:ActiveRecord::StatementInvalid

SQLite3::SQLException: row value misused: SELECT COUNT(*) AS count_all, strftime('%Y-%m-%d 00:00:00 UTC', "users"."created_at") AS strftime_y_m_d_00_00_00_utc_users_created_at FROM "users" INNER JOIN "visits" ON "visits"."user_id" = "users"."id" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE (visits.user_id = 1, posts.user_id = 1) AND (visits.created_at >= '2020-01-20 00:00:00' AND visits.created_at <= '2020-02-02 00:00:00') AND (posts.created_at >= '2020-01-20 00:00:00' AND posts.created_at <= '2020-02-02 00:00:00') AND ("users"."created_at" >= '2020-01-20 00:00:00' AND "users"."created_at" <= '2020-02-04 19:03:28.383850') GROUP BY strftime('%Y-%m-%d 00:00:00 UTC', "users"."created_at")

我的模特:

class Visit < ApplicationRecord
  belongs_to :user
end

class Post < ApplicationRecord
    belongs_to :user
end

class User < ApplicationRecord
  has_many :visits
  has_many :posts
end

我一直在环顾四周,尝试了几种不同的方法,但都没有运气。 任何 rails 的帮助只是 plain sql 或提示非常感谢并提前感谢!

【问题讨论】:

    标签: sql activerecord ruby-on-rails-5.2


    【解决方案1】:

    试试这个:

    _start_time = 15.days.ago.midnight.in_time_zone("Berlin") ## get start time
    _end_time = 2.days.ago.midnight.in_time_zone("Berlin") ## get end time
    
     #### query ###
    User.joins(:visits, :posts).where(visits: { created_at: (_start_time.._end_time) }).where(posts: { created_at: (_start_time.._end_time) }).group_by_day(:created_at, range: _start_time..Time.now.in_time_zone("Berlin"), format: "%d %b").count
    

    【讨论】:

    • 谢谢@prakash。 sql 输出是 SELECT COUNT(*) AS count_all, strftime('%Y-%m-%d 00:00:00 UTC', "users"."created_at") AS strftime_y_m_d_00_00_00_utc_users_created_at FROM "users" INNER JOIN "visits" ON "visits"."user_id" = "users"."id" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE "visits"."created_at" BETWEEN ? AND ? AND "posts"."created_at" BETWEEN ? AND ? AND ("users"."created_at" &gt;= '2020-01-21 00:00:00' AND "users"."created_at" &lt;= '2020-02-05 18:55:01.042324') GROUP BY strftime('%Y-%m-%d 00:00:00 UTC', "users"."created_at") 并且花费了 719639.1ms 并且输出错误:/
    • @Rubioli 在您的查询中,您在两个表上都使用 created_at 来过滤数据,并且看起来您没有任何索引,这就是查询需要很长时间才能获得输出的原因。请分享您期望的输出并提供更多详细信息。
    • 感谢您的回复。我将索引添加到created_at 并且仍然很慢。我正在寻找的是获取用户的 visits & post 按天分组
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多