Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Пересечение диапозонов дат / 15 сообщений из 15, страница 1 из 1
27.03.2014, 19:14:51
    #38598444
Пересечение диапозонов дат
есть таблица:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE schedule (
schedule_id numeric(10) NOT NULL,
employee_id numeric(10) NOT NULL,
startdatetime datetime NOT NULL,
enddatetime datetime NOT NULL,
PRIMARY KEY (schedule_id)
);



Нужно найти пользователей(employee_id ) у которых есть пересечение диапазонов дат.

ожидаю примерно такой результат:
1000000,1000371,2013-02-13 06:00:00,2013-02-13 15:00:00
1000001,1000371,2013-02-13 12:00:00,2013-02-13 18:00:00
...
...
Рейтинг: 0 / 0
27.03.2014, 19:26:06
    #38598452
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение диапозонов дат
с точностью до синтаксиса решение в лоб (ибо нет количественных характеристик сервера).

Код: sql
1.
2.
3.
4.
5.
select 
 * 
from schedule  SH
  join schedule OSH on SH.employee_id = SH.employee_id and OSH.schedule_id <> SH.schedule_id and 
((OSH.startdatetime between SH.startdatetime and SH.enddatetime) OR (OSH.enddatetime between SH.startdatetime and SH.enddatetime))
...
Рейтинг: 0 / 0
27.03.2014, 20:59:00
    #38598513
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение диапозонов дат
Код: sql
1.
2.
3.
4.
select t1.*, t2.*
from schedule t1, schedule t2
where t1.employee_id = t2.employee_id
and t2.startdatetime between t1.startdatetime and t1.enddatetime
...
Рейтинг: 0 / 0
27.03.2014, 22:15:55
    #38598563
Пересечение диапозонов дат
от первого запроса бд упала, а от второй выдал больше строк в результате чем есть в таблице.

нужны только те строки которые пересекаются между собой
...
Рейтинг: 0 / 0
28.03.2014, 05:15:45
    #38598673
Пересечение диапозонов дат
Грек Финский,

если вспомнить курс школьной математики за 5-й класс, где проходят числовой луч и работу с отрезками, то станет ясно - два отрезка пересекаются (имеют одну и более общих точек), если каждое из кончал отрезков больше каждого из начал этих отрезков.
ну или в терминах твоей таблицы:

Код: sql
1.
2.
3.
4.
5.
6.
select * 
  from schedule s1 
  join schedule s2 
    on s1.schedule_id != s2.schedule_id 
   and s1.enddatetime >= s2.startdatetime 
   and s2.enddatetime >= s1.startdatetime
...
Рейтинг: 0 / 0
28.03.2014, 06:30:11
    #38598680
Пересечение диапозонов дат
Грек Финскийвторой выдал больше строк в результате чем есть в таблице.При джойне - это нормально. Ибо каждое пересечение будет "умножать" строки исходной таблицы. Если нужно вывести строки, для которых существует пересечение по дате, при этом не пристыковывать "сбоку" те строки, с которыми есть пересечение, то нужно JOIN заменять на EXISTS-подзапрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select * 
  from schedule s1 
 where exists
        (
          select null
            from schedule s2 
           where s1.schedule_id != s2.schedule_id 
             and s1.enddatetime >= s2.startdatetime 
             and s2.enddatetime >= s1.startdatetime
        )
...
Рейтинг: 0 / 0
28.03.2014, 11:41:31
    #38598937
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение диапозонов дат
Грек Финский от второй выдал больше строк в результате чем есть в таблице.
Замените benween на два неравенства. Причём первое сделайте строгим.
...
Рейтинг: 0 / 0
28.03.2014, 12:38:16
    #38599029
bochkov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение диапозонов дат
Добрый Э - ЭхГрек Финский,

если вспомнить курс школьной математики за 5-й класс, где проходят числовой луч и работу с отрезками, то станет ясно - два отрезка пересекаются (имеют одну и более общих точек), если каждое из кончал отрезков больше каждого из начал этих отрезков.
ну или в терминах твоей таблицы:

Код: sql
1.
2.
3.
4.
5.
6.
select * 
  from schedule s1 
  join schedule s2 
    on s1.schedule_id != s2.schedule_id 
   and s1.enddatetime >= s2.startdatetime 
   and s2.enddatetime >= s1.startdatetime



а вот такой запрос как правило быстрее будет работать
Код: sql
1.
2.
3.
4.
5.
6.
select * 
  from schedule s1 
  join schedule s2 
    on s1.schedule_id != s2.schedule_id 
   and s2.startdatetime BETWEEN s1.startdatetime AND s1.enddatetime 
   and s1.startdatetime BETWEEN s2.startdatetime AND s2.enddatetime
...
Рейтинг: 0 / 0
28.03.2014, 12:45:03
    #38599039
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение диапозонов дат
bochkovДобрый Э - ЭхГрек Финский,

если вспомнить курс школьной математики за 5-й класс, где проходят числовой луч и работу с отрезками, то станет ясно - два отрезка пересекаются (имеют одну и более общих точек), если каждое из кончал отрезков больше каждого из начал этих отрезков.
ну или в терминах твоей таблицы:

Код: sql
1.
2.
3.
4.
5.
6.
select * 
  from schedule s1 
  join schedule s2 
    on s1.schedule_id != s2.schedule_id 
   and s1.enddatetime >= s2.startdatetime 
   and s2.enddatetime >= s1.startdatetime




а вот такой запрос как правило быстрее будет работать
Код: sql
1.
2.
3.
4.
5.
6.
select * 
  from schedule s1 
  join schedule s2 
    on s1.schedule_id != s2.schedule_id 
   and s2.startdatetime BETWEEN s1.startdatetime AND s1.enddatetime 
   and s1.startdatetime BETWEEN s2.startdatetime AND s2.enddatetime

Может и быстрее, но неправильно. Там OR нужен.
...
Рейтинг: 0 / 0
28.03.2014, 12:48:58
    #38599051
Пересечение диапозонов дат
bochkov,

скорее всего - как исключение, а не как правило.
ну и без убедительных доказательных аргументов в виде планов запросов и статистики выполнения - не считово. ;)
...
Рейтинг: 0 / 0
28.03.2014, 12:52:59
    #38599056
Пересечение диапозонов дат
bochkovа вот такой запрос как правило быстрее будет работать
Код: sql
1.
2.
3.
4.
5.
6.
select * 
  from schedule s1 
  join schedule s2 
    on s1.schedule_id != s2.schedule_id 
   and s2.startdatetime BETWEEN s1.startdatetime AND s1.enddatetime 
   and s1.startdatetime BETWEEN s2.startdatetime AND s2.enddatetime

выделенное - всегда тождественно ложно. Посему запрос изначально - нерабочий. Если даже предположить, что он бстрее, то всё одно грош цена ему. Ибо он не делает главного - не решает поставленной задачи :)
...
Рейтинг: 0 / 0
28.03.2014, 12:56:46
    #38599065
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение диапозонов дат
Добрый Э - Эхbochkovа вот такой запрос как правило быстрее будет работать
Код: sql
1.
2.
3.
4.
5.
6.
select * 
  from schedule s1 
  join schedule s2 
    on s1.schedule_id != s2.schedule_id 
   and s2.startdatetime BETWEEN s1.startdatetime AND s1.enddatetime 
   and s1.startdatetime BETWEEN s2.startdatetime AND s2.enddatetime


выделенное - всегда тождественно ложно.Не всегда. За исключением случая, когда s1.startdatetime=s2.startdatetime
...
Рейтинг: 0 / 0
28.03.2014, 13:19:16
    #38599104
Пересечение диапозонов дат
запросы роняют БД (вылетает по таймауту)

Немного поправил второй предложенный запрос:
Код: plsql
1.
select t1.*, t2.* from schedule t1, schedule t2 where t1.employee_id = 1000003 and t2.employee_id = 1000003 and t1.schedule_id != t2.schedule_id and t2.startdatetime between t1.startdatetime and t1.enddatetime



делает почти то что нужно, с остальным разберусь, спасибо всем за помощь
...
Рейтинг: 0 / 0
28.03.2014, 13:25:26
    #38599118
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение диапозонов дат
Грек Финскийзапросы роняют БД (вылетает по таймауту)А индексов, конечно, нет?
...
Рейтинг: 0 / 0
28.03.2014, 13:57:01
    #38599154
bochkov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пересечение диапозонов дат
сделал испытание,
что то результаты разные получились,
индекс date_from, date_to
прирост производительности налицо,
почему результаты разные никак не пойму,
я в свое время с этими периодами долго ковырялся, не мог этого не заметить
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
*************************** 1. row ***************************
sql: SELECT SQL_NO_CACHE COUNT(*) FROM permit_period2 pp;
*************************** 1. row ***************************
COUNT(*): 383106
*************************** 1. row ***************************
sql: EXPLAIN SELECT SQL_NO_CACHE COUNT(*) FROM permit_period2 pp WHERE pp.date_from BETWEEN '2013-01-01' AND '2013-01-31' AND '2013-01-01' BETWEEN pp.date_from AND pp.date_to;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: pp
         type: range
possible_keys: date_period_index
          key: date_period_index
      key_len: 4
          ref: NULL
         rows: 25582
        Extra: Using where; Using index
*************************** 1. row ***************************
sql: SELECT SQL_NO_CACHE COUNT(*) FROM permit_period2 pp WHERE pp.date_from BETWEEN '2013-01-01' AND '2013-01-31' AND '2013-01-01' BETWEEN pp.date_from AND pp.date_to;
*************************** 1. row ***************************
COUNT(*): 24351
*************************** 1. row ***************************
sql: EXPLAIN SELECT SQL_NO_CACHE COUNT(*) FROM permit_period2 pp WHERE pp.date_from <= '2013-01-31' AND '2013-01-01' <= pp.date_to;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: pp
         type: range
possible_keys: date_period_index
          key: date_period_index
      key_len: 4
          ref: NULL
         rows: 203503
        Extra: Using where; Using index
*************************** 1. row ***************************
sql: SELECT SQL_NO_CACHE COUNT(*) FROM permit_period2 pp WHERE pp.date_from <= '2013-01-31' AND '2013-01-01' <= pp.date_to;
*************************** 1. row ***************************
COUNT(*): 26993
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Пересечение диапозонов дат / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]