Ruby Gem Squeel, как написать сам присоединиться

Я пытаюсь написать следующий запрос, используя рубиновый камень 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.where{season_id.in(seasons.select{id})}

но я присоединяюсь к условию, я понятия не имею, как справиться с этим до сих пор.

1 ответ

Это похоже на то, что я пытался сделать здесь.

Я бы попробовал использовать подзапрос, соединив Period с собой следующим образом:

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

  belongs_to :season

  scope :in_seasons, ->(season_ids) { joins{season}.where{id.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`}.having{end_at < `min(self_join.start_at)`}
  end
end

В рельсах консоли, 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)

Похоже, что вы пытаетесь получить... по крайней мере, внутреннюю часть.

Надеюсь, поможет.

Другие вопросы по тегам