Ruby Gem Squeel,如何编写自联接

Posted

技术标签:

【中文标题】Ruby Gem Squeel,如何编写自联接【英文标题】:Ruby Gem Squeel, how to write self join 【发布时间】:2013-04-29 20:30:41 【问题描述】:

我正在尝试使用 ruby​​ gem Squeel 编写以下查询

SELECT COUNT(*)
FROM(
  SELECT
    a.end_at AS START,
    Min(b.start_at) AS END
  FROM periods AS a
  JOIN periods AS b ON b.season_id IN (1,2,3) AND a.end_at <= b.start_at
  WHERE a.season_id IN (1,2,3)
  GROUP BY a.end_at
  HAVING a.end_at < MIN(b.start_at)
) AS gaps
WHERE
  gaps.START < '2013-05-17' AND gaps.END > '2013-05-05';

知道如何实现这一目标吗?

我可以使用以下方法获取 seasons_ids:

seasons = self.seasons
Period.whereseason_id.in(seasons.selectid)

但是自我加入条件,到目前为止我不知道如何解决这个问题。

【问题讨论】:

【参考方案1】:

这类似于我尝试做的here。

我会尝试使用子查询,将 Period 加入自身,如下所示:

class Period < ActiveRecord::Base
  attr_accessible :end_at, :season_id, :start_at

  belongs_to :season

  scope :in_seasons, ->(season_ids)  joinsseason.whereid.in(season_ids) 

  def self.find_gaps(start_date, end_date)
    season_ids = ["1", "2", "3"]
    scope = select[end_at.as(`gap_start`), `min(self_join.start_at)`.as(`gap_end`)]
    scope = scope.joins"LEFT JOIN (" + Period.in_seasons(season_ids).to_sql + ") AS self_join ON self_join.end_at <= periods.start_at"
    scope = scope.where(`self_join.start_at` != nil) & (`gap_start` < start_date) & (`gap_end` > end_date)
    scope = scope.group`gap_end`.havingend_at < `min(self_join.start_at)`
  end
end

在 Rails 控制台中,Period.find_gaps('2001-01-01', '2010-01-01').to_sql 产生(格式是我自己的):

SELECT 
  \"periods\".\"end_at\" AS gap_start, 
  min(self_join.start_at) AS gap_end 
FROM \"periods\" 
  LEFT JOIN 
    (SELECT \"periods\".* 
     FROM \"periods\" 
       INNER JOIN \"seasons\" ON \"seasons\".\"id\" = \"periods\".\"season_id\" 
     WHERE \"periods\".\"id\" IN (1, 2, 3)
    ) AS self_join ON self_join.end_at <= periods.start_at 
WHERE ((self_join.start_at IS NOT NULL AND gap_start < '2001-01-01' AND gap_end > '2010-01-01')) 
GROUP BY gap_end 
HAVING \"periods\".\"end_at\" < min(self_join.start_at)

看起来你想要达到的效果......至少是内部部分。

希望对你有帮助。

【讨论】:

以上是关于Ruby Gem Squeel,如何编写自联接的主要内容,如果未能解决你的问题,请参考以下文章

需要帮助重新编写一些最初使用名为 Squeel 的 gem 编写的 Rails DB 查询,具有有效的 SQL

Ruby:如何写一个 gem? [关闭]

如何从自联接中删除两行

如何在自联接中获取唯一值以及如何在 psql 中动态获取 LIMIT 数

如何改进包含存储过程使用的多个自联接的视图

我需要帮助重新编写一个最初用 Squeel 编写的额外数据库查询,我尝试了各种语法,但似乎无法理解