0

テーブルの行を取得しようとしています。

2つのレコード(t1とt2)を取得したと想像してください。t2.start_hourとt2.finish_hourの間にt1.start_hourがない行を取得したいと思います。基本的に、他のオカレンスと数時間で競合しないオカレンスのみを取得したいと思います。

これは表です:

create_table "occurrences", :force => true do |t|
    t.string   "start_hour"
    t.string   "finish_hour"
    t.date     "start_date"
    t.date     "finish_date"
    t.datetime "created_at",  :null => false
    t.datetime "updated_at",  :null => false
    t.integer  "activity_id"
  end

そして、これは私がこれまでに思いついたSQLクエリです。

Occurrence.find_by_sql("SELECT * FROM occurrences t1 INNER JOIN occurrences t2 ON (t1.start_hour NOT BETWEEN t2.start_hour and t2.finish_hour)")

それは私に重複した結果を与えます。それらを削除して正しい答えを得ることができません。

よろしくお願いします。

入力

#<Occurrence id: 1, start_hour: "19:00", finish_hour: "20:20", start_date: "2012-05-30", finish_date: "2012-05-30", created_at: "2012-05-30 09:58:19", updated_at: "2012-05-30 09:58:19", activity_id: 1>, 

#<Occurrence id: 2, start_hour: "19:30", finish_hour: "20:10", start_date: "2012-05-30", finish_date: "2012-05-30", created_at: "2012-05-30 09:58:19", updated_at: "2012-05-30 09:58:19", activity_id: 2>,

#<Occurrence id: 3, start_hour: "22:00", finish_hour: "23:20", start_date: "2012-05-30", finish_date: "2012-05-30", created_at: "2012-05-30 09:58:20", updated_at: "2012-05-30 09:58:20", activity_id: 3>

出力

#<Occurrence id: 1, start_hour: "19:00", finish_hour: "20:20", start_date: "2012-05-30", finish_date: "2012-05-30", created_at: "2012-05-30 09:58:19", updated_at: "2012-05-30 09:58:19", activity_id: 1>, 

#<Occurrence id: 3, start_hour: "22:00", finish_hour: "23:20", start_date: "2012-05-30", finish_date: "2012-05-30", created_at: "2012-05-30 09:58:20", updated_at: "2012-05-30 09:58:20", activity_id: 3>

start_hour = 19:30のレコードは、別のレコードの19:00から20:20の間にあるため、出力されません。

編集:

私は解決策を得ました:

Occurrence.find_by_sql("SELECT start_hour FROM occurrences WHERE start_hour NOT IN (SELECT t2.start_hour FROM occurrences t1 INNER JOIN occurrences t2 ON ((t1.activity_id <> t2.activity_id AND t2.start_hour BETWEEN t1.start_hour and t1.finish_hour)))")

助けてくれてありがとう

4

2 に答える 2

0

テストされていません (メモリから) レコード自体を除外する必要があります --> t1.activity_id <> t2.activity_id 左結合。

これをテストする必要があります:p

SELECT * FROM occurrences t1 
left JOIN occurrences t2 
ON (t1.activity_id <> t2.activity_id and t1.start_hour BETWEEN t2.start_hour and t2.finish_hour)
where t2.activity_id is null
于 2012-05-30T10:13:28.597 に答える
0

テーブルに 3 つのレコードがあるとします。(これが簡単になるので、datatime の代わりに整数を使用しています)

  id     start    end
   1      1        3
   2      4        5
   3      7        9

id = 1 の場合よりも、開始が開始と終了の間にない行を見つけようとすると、両方の最初の行が真になり、結果が得られます。同様に、id =2 (start=4) の行の場合、両方の行が対象となります (結果として 3 行目が 2 回表示されます)。3 行目でも同じことが起こり、最終的に 6 行になります。

ここで何を達成しようとしているのかは明確ではありませんが、個別に配置すると重複が削除されます。

編集:開始日と終了日に内部結合を配置することを検討してください。

于 2012-05-30T10:01:06.430 に答える