2012-05-30 6 views
0

Я пытаюсь получить строки в таблице.Получение строк в одной таблице

Представьте, что у меня две записи (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)") 

Это дает мне продублировать результаты. Я не смогу удалить их и получить правильный ответ.

Спасибо за помощь заранее.

Пример

ВХОД

#<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 в другой ,

EDIT:

Я получил решение:

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

Спасибо за помощь

+0

Пожалуйста, после некоторых выборочных данных и ожидаемых результатов. – Quassnoi

+0

Я не мог понять, чего вы пытаетесь достичь здесь. Было бы лучше, если бы вы могли предоставить нам более подробную информацию о проблеме реального мира, которую вы пытаетесь решить этим. – rubish

ответ

0

Пусть Предположим, есть 3 записей в таблице. (Я принимаю целое число вместо datatime, так как это будет легче)

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

Когда я попытаюсь найти строки были старт не между началом и концом, чем для ID = 1, как первая строка будет true и придет в результате. Аналогично для строки с id = 2 (start = 4) обе строки будут квалифицироваться (сделать третью строку в два раза больше). То же самое произойдет и для третьей строки, и вы получите шесть строк.

Его не очень ясно, что вы пытаетесь достичь здесь, но придание четкости удалит дубликат.

РЕДАКТИРОВАТЬ: Вы можете рассмотреть возможность ввода внутренних объединений в дату начала и окончания.

0

не тестировался (из памяти) вам нужно Exlude самого рекорда -> t1.activity_id <> t2.activity_id покинул присоединиться или вы не получите хорошие где нет правой стороны

должны были бы проверить это: р

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 
+0

В результате получается две записи со всеми полями с нулевым значением. EDIT: количество записей os правильно. –

Смежные вопросы