2013-06-12 1 views
0

В моей таблице базы данных MySQL я следующие даты периоды (сезоны):Дата период распространилась среди сезонов

sstart,send,sname 
2013-05-01,2013-05-31,'season1' 
2013-06-01,2013-06-30,'season2' 

Я хотел бы создать SQL запрос, который будет для данной даты начала и окончания раскола этот период среди сезоны с информацией о продолжительности каждой части периода:

Например, для следующего периода (QSTART, qend) 2013-04-20,2013-06-10 этот запрос должен возвращать:

2013-04-20,2013-04-30,'',11   <-- this is important - I need it 
2013-05-01,2013-05-31,'season1',31 <-- 31 days of my period is in season1 
2013-06-01,2013-06-10,'season2',10 <-- 10 days of my period is in season2 

I иметь следующий SQL-запрос:

SELECT sid,sname,DATEDIFF(IF(send>@qend,@qend,send),IF(sstart<@qstart,@qstart,sstart))+1 
       FROM seasons WHERE sstart<[email protected] AND send>[email protected] 

Моя проблема в том, когда мой период (QSTART, qend) до момента начала первого сезона или заканчивается после последнего сезона в базе данных, этот запрос не возвращает эти хвосты, которые мне нужны.

ответ

0

Я не MySql, но следует надеяться, направить вас в правильном направлении:

Вместо таблицы Сезонов в запросе, используя следующее:

FROM 
    ( 
    select * from seasons 
    union 
    select '' as [sname],'1/1/1980' as [sStart],DateAdd(dd,-1,MIN([sStart])) as [send] 
    from Seasons 
    union 
    select '' as [sname],DateAdd(dd,+1,MAX([send])) as [sstart],'12/31/2021' as [Send] 
    from Seasons 
    ) Seasons   

В основном, добавив два «фиктивные строки» для представления сезонов до первой даты и после последней даты ...

+0

Спасибо за такой быстрый ответ. Я прочитал об этом решении с добавлением фиктивных строк (и объединил их), но думал, что это грязное решение. Если никто не предложит ничего лучшего, мне придется принять это как единственное решение. – sbrbot

+0

Почему грязное решение? Конечно, вы могли бы добавить фиктивные строки в свою таблицу, если вы будете называть это много раз, но я полагаю, что таблица ваших сезонов очень мала, поэтому заявление о союзе, которое я проиллюстрировал, не займет много времени, чтобы запустить вообще. .. Вы также должны использовать UNION ALL вместо UNION, так как новые строки никогда не будут дублировать существующие строки ... – Sparky

+0

Спасибо Sparky, ваше предложение было полезно. – sbrbot

0

для других, согласно предложению Спарки здесь мой запрос:

SELECT sid,sstart,send,sname,DATEDIFF(IF(send>@lDay,@lDay,send),IF(sstart<@fDay,@fDay,sstart))+1 AS duration 
FROM 
(
    SELECT 0 AS sid,'undefined' AS sname,'1980-01-01' AS sstart,SUBDATE(MIN(sstart),1) AS send FROM seasons 
    UNION 
    SELECT sid,sname,sstart,send FROM seasons 
    UNION 
    SELECT 0 AS sid,'undefined' AS sname,ADDDATE(MAX(send),1) AS sstart,'2021-12-31' AS send FROM seasons 
) AS seasons 
WHERE sstart<[email protected] AND send>[email protected] 
ORDER BY sstart 
+0

Незначительное примечание, перейдите в UNION ALL, чтобы получить немного производительности – Sparky