powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Пересечение диапозонов дат
15 сообщений из 15, страница 1 из 1
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #38598563
от первого запроса бд упала, а от второй выдал больше строк в результате чем есть в таблице.

нужны только те строки которые пересекаются между собой
...
Рейтинг: 0 / 0
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #38598937
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Грек Финский от второй выдал больше строк в результате чем есть в таблице.
Замените benween на два неравенства. Причём первое сделайте строгим.
...
Рейтинг: 0 / 0
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #38599051
bochkov,

скорее всего - как исключение, а не как правило.
ну и без убедительных доказательных аргументов в виде планов запросов и статистики выполнения - не считово. ;)
...
Рейтинг: 0 / 0
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #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
Пересечение диапозонов дат
    #38599118
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Грек Финскийзапросы роняют БД (вылетает по таймауту)А индексов, конечно, нет?
...
Рейтинг: 0 / 0
Пересечение диапозонов дат
    #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
15 сообщений из 15, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Пересечение диапозонов дат
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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