Правила     Закладки     Карма    Календарь    Журналы    Помощь    Поиск    PDA    Чат   
        СМС-ки
   
Пейджер выключен!
 
Фильтр авторов:    показать 
  скрыть
  Ответ в темуСоздание новой темыСоздание опроса

> Группировка пересекающихся интервалов
kaww  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1785
Пользователь №: 20757
На форуме: 7 лет, 4 месяца, 22 дня
Карма: 186




Всем привет!
Имеем таблицу, которая содержит временные интервалы вида:
+---------------------+---------------------+
| date_from | date_to |
+---------------------+---------------------+
| 2017-01-01 00:00:00 | 2017-01-01 00:00:10 |
| 2017-01-01 00:00:11 | 2017-01-01 00:10:00 |
| 2017-01-01 00:10:20 | 2017-01-01 00:30:00 |
| 2017-01-01 00:29:00 | 2017-01-01 00:30:10 |
| 2017-01-01 01:00:00 | 2017-01-01 02:00:00 |
| 2017-01-01 02:00:00 | 2017-01-01 04:00:00 |
| 2017-01-01 05:00:00 | 2017-01-01 08:00:00 |
+---------------------+---------------------+

необходимо получить из нее нечто подобное
+---------------------+---------------------+
| date_from | date_to |
+---------------------+---------------------+
| 2017-01-01 00:00:00 | 2017-01-01 00:00:10 |
| 2017-01-01 00:00:11 | 2017-01-01 00:10:00 |
| 2017-01-01 00:10:20 | 2017-01-01 00:30:10 |
| 2017-01-01 01:00:00 | 2017-01-01 04:00:00 |
| 2017-01-01 05:00:00 | 2017-01-01 08:00:00 |
+---------------------+---------------------+

т.е. сгруппировать по пересекающимся интервалам, что из 2017-01-01 01:00:00-2017-01-01 02:00:00 и 2017-01-01 02:00:00- 2017-01-01 04:00:00 получилось 2017-01-01 01:00:00-2017-01-01 04:00:00
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
bestxp  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



орангутанг
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 2064
Пользователь №: 36605
На форуме: 4 года, 4 месяца, 8 дней
Карма: 113




любопытно даже, такой кошмар помню на PHP разруливал, интересно на SQL может кто покажет, но кмк без хранимки никак особенно если они не в стыке соединяються, а пересекаються о_О
PMПисьмо на e-mail пользователюСайт пользователяICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
kaww  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1785
Пользователь №: 20757
На форуме: 7 лет, 4 месяца, 22 дня
Карма: 186




Получилось это. Пока не до конца уверен, что работает верно (И действительно, работает неверно). Может что-нибудь лучше удастся найти. Да и join пришлось заюзать:
SELECT 
MIN(date_from), MAX(date_to)
FROM (
SELECT
IF
(MIN(i1.date_from) <= MIN(IFNULL(i2.date_from, i1.date_from)), MIN(i1.date_from), MIN(i2.date_from)) AS date_from,
IF(MAX(i1.date_to) >= MAX(IFNULL(i2.date_to, i1.date_to)), MAX(i1.date_to), MAX(i2.date_to)) AS date_to
FROM intervals AS i1
LEFT JOIN intervals AS i2 ON i1.id>i2.id AND (i1.date_from BETWEEN i2.date_from AND i2.date_to OR i2.date_from BETWEEN i1.date_from AND i1.date_to)
GROUP BY i1.date_from) AS tmp
GROUP BY date_from

http://sqlfiddle.com/#!9/f244f2/2
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
kaww  
 ۩  [x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1785
Пользователь №: 20757
На форуме: 7 лет, 4 месяца, 22 дня
Карма: 186




Вариант на php (который тоже оказался не рабочим):
$data = [
[
'from' => '2017-01-01 00:00:00', 'to' => '2017-01-01 00:00:10'],
[
'from' => '2017-01-01 00:00:11', 'to' => '2017-01-01 00:10:00'],
[
'from' => '2017-01-01 00:10:20', 'to' => '2017-01-01 00:30:00'],
[
'from' => '2017-01-01 00:29:00', 'to' => '2017-01-01 00:30:10'],
[
'from' => '2017-01-01 01:00:00', 'to' => '2017-01-01 02:00:00'],
[
'from' => '2017-01-01 02:00:00', 'to' => '2017-01-01 04:00:00'],
[
'from' => '2017-01-01 05:00:00', 'to' => '2017-01-01 08:00:00'],
];

$intervals = [];
foreach ($data as $item) {
$from = strtotime($item['from']);
$to = strtotime($item['to']);
$f = false;
foreach ($intervals as &$interval) {
if (($from >= $interval['from'] && $from <= $interval['to'])
|| (
$to >= $interval['from']) && $to <= $interval['to']) {
if ($interval['from'] > $from) {
$interval['from'] = $from;
}
if ($interval['to'] < $to) {
$interval['to'] = $to;
}
$f = true;
break;
}
}

if (!$f) {
$intervals[] = ['from' => $from, 'to' => $to];
}
}

unset($interval);
//Debug output:
foreach ($intervals as $interval) {
echo date('Y-m-d H:i:s', $interval['from']), ' - ', date('Y-m-d H:i:s', $interval['to']), PHP_EOL;
}
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
depp  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 388
Пользователь №: 40589
На форуме: 2 года, 6 месяцев, 20 дней
Карма: 22




а не напрашивался ли случайно у вас вопрос о том, а правильно ли вообще составлена архитектура бд?
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
T1grOK  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 2789
Пользователь №: 24406
На форуме: 6 лет, 8 месяцев, 7 дней
Карма: 180




if (($from >= $interval['from'] && $from <= $interval['to'])
|| (
$to >= $interval['from']) && $to <= $interval['to']) {

Достаточно

if ($from <= $interval['to'] && $to >= $interval['from']) {


--------------------
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
PMПисьмо на e-mail пользователюСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
sergeiss  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Сидел он, дум великих полон - и вдаль глядел
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 15381
Пользователь №: 4190
На форуме: 9 лет, 4 месяца, 18 дней
Карма: 470




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

select
date_from,
case when date_to_2 is null then date_to else date_to_2 end as date_to

from
(
select
date_from,
date_to,
(
select date_from from times where t.date_from>date_from and t.date_from<=date_to limit 1) as date_from_2,
(
select date_to from times where t.date_from>date_from and t.date_from<=date_to limit 1) as date_to_2,
(
select date_from from times where t.date_from<date_from and t.date_to>=date_from limit 1) as date_from_3,
(
select date_to from times where t.date_from<date_from and t.date_to>=date_from limit 1) as date_to_3
from times t
) initial_selection

where date_from_2 is null

order by
date_from

Для твоих исходных данных (и при озвученных мной условиях) дает ожидаемый результат
date_from, date_to
'2017-01-01 00:00:00', '2017-01-01 00:00:10'
'2017-01-01 00:00:11', '2017-01-01 00:10:00'
'2017-01-01 00:10:20', '2017-01-01 00:30:00'
'2017-01-01 01:00:00', '2017-01-01 02:00:00'
'2017-01-01 05:00:00', '2017-01-01 08:00:00'



--------------------
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
PMICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
kaww  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1785
Пользователь №: 20757
На форуме: 7 лет, 4 месяца, 22 дня
Карма: 186




Оказалось, что предыдущий запрос работает неправильно (как будто в этом были сомнения). Еще вариант. Без джоинов и, вроде,работает по-лучше предыдущего:
SET @dt := NOW() - INTERVAL 10 YEAR;
SET @gt := 0;
SELECT
MIN(date_from),
MAX(date_to),
GROUP_CONCAT(id) AS debug
FROM (
SELECT
id,
date_from,
date_to,
IF(@dt >= date_from, @gt, @gt := id) AS gt,
@dt := date_to AS dummy
FROM intervals
ORDER BY date_from) AS t
GROUP BY gt

http://sqlfiddle.com/#!9/1bf5f4/2
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Valick  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 5625
Пользователь №: 35718
На форуме: 4 года, 7 месяцев, 4 дня
Карма: 173




Цитата (depp @ 15.02.2017 - 15:48)
а правильно ли вообще составлена архитектура бд?



--------------------
wmr - R281553014107
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
bestxp  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



орангутанг
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 2064
Пользователь №: 36605
На форуме: 4 года, 4 месяца, 8 дней
Карма: 113




Цитата (Valick @ 16.02.2017 - 19:36)
Цитата (depp @ 15.02.2017 - 15:48)
а правильно ли вообще составлена архитектура бд?

по одной таблице судить не можем мы)
PMПисьмо на e-mail пользователюСайт пользователяICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
  Быстрый ответ
Информация о Госте
Введите Ваше имя
Кнопки кодов
Для вставки цитаты, выделите нужный текст и
НАЖМИТЕ СЮДА
Введите сообщение
Смайлики
:huh:  :o  ;) 
:P  :D  :lol: 
B)  :rolleyes:  <_< 
:)  :angry:  :( 
:unsure:  :blink:  :ph34r: 
     
Показать всё

Опции сообщения  Включить смайлики?
 Включить подпись?
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:

Опции темы Ответ в темуСоздание новой темыСоздание опроса