2012-03-05 14 views
1

季節を重ねて下さい?私はすでにいくつかの異なる質問(下記)で試してみました。しかし、私が打ち続ける問題は、シーズンにも可能性のチェックが複数のdate_rangesを持つという事実です。私はループでそれを解決することができますが、私はむしろクエリを使用したいと思います。私は次のセットアップを持っている季節have_many date_ranges

このクエリは、重複するすべての季節を検索しますが、それは唯一の) Season.joins(:date_ranges).where("starts_at <= ? AND ends_at >= ?", ends_at, starts_at DATE_RANGE 1つの入力用

たぶん私は、インスタンス上の各DATE_RANGEのORののカップル一緒にチェーンに何かを必要とするが、where()のみ使用することを行いますそして。

要するに、重複を見つけることは問題ではありませんが、データベース全体に対して複数のdate_rangesの重複を見つけるにはどうすればよいですか?

+0

可能であれば、他の人と互換性があるようにしたいと思います – Ralph

答えて

0

最も簡単な方法は、まっすぐなSQLです。

DateRange.find_by_sql(%q{ 
    select a.* 
    from date_ranges a 
    join date_ranges b on 
      a.id < b.id 
     and (
       (a.ends_at >= b.starts_at and a.ends_at <= b.ends_at) 
      or (a.starts_at >= b.starts_at and a.starts_at <= b.ends_at) 
      or (a.starts_at <= b.starts_at and a.ends_at >= b.ends_at) 
     ) 
    where season_id = ? 
}, season_id) 

基本的な考え方は、範囲を簡単に比較できるようにテーブルを結合することです。 a.id < b.idには独自の結果が得られ、「範囲一致」のケースが除外されます。そのクエリは、彼らだけで一致した場合に重なるように2つの間隔を考慮し、

[as-----ae]   [as-----ae]  
    [bs-----be] [bs-----be] 

[as--------------ae]   [as----ae] 
    [bs----be]   [bs--------------be] 

あなたはかかわらず、エンドポイントについて考えたいかもしれませんが:インナーor条件は重複の両方のタイプをチェックしますそれはあなたが望むものではないかもしれません。

恐らく(season_id, starts_at, ends_at)トリプルにはユニークな制約があります。既にstarts_at <= ends_atが確実に存在していると思われます。

関連する問題