在同一个表中获取行

时间:2012-05-30 09:47:39

标签: sql ruby-on-rails-3

我正在尝试在表中获取行。

想象一下,我有两条记录(t1和t2)。我想获得没有t1.start_hour BETWEEN t2.start_hour和t2.finish_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)")

它给了我重复的结果。我无法移除它们并得到正确答案。

感谢您的帮助。

实施例

INPUT

#<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)))")

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

假设表中有3条记录。 (我使用整数代替数据时间,因为这会更容易)

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

当我试图找到行时,start不在start和end之间,而对于id = 1,第一行都将为true并且将在结果中出现。类似地,对于id = 2(start = 4)的行,两行都将符合条件(使第三行在结果中出现两次)第三行会出现相同的情况,最后会有六行。

你在这里想要实现的目标并不十分清楚,但是使用distinct会删除副本。

编辑:您可以考虑将内部联接放在开始和结束日期。

答案 1 :(得分:0)

未经测试(来自内存) 你需要排除记录本身 - &gt; t1.activity_id&lt;&gt; 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