Заполнение пробелов парами дат начала и окончания

Состояние:

Start date: 31-12-2012  
End date:   01-04-2013
  • module represents project_id
  • loading represents that between module_start_date and module_end_date and user_id=6 is 40 percent free.
SELECT [user_id], module_id, module_start_date, module_end_date,
            1 - loading_percentage loading
FROM module_user_master_map
WHERE module_start_date >= '2012-12-31'
      AND module_end_date <= '2013-04-01'
      AND [user_id]=6

Используя этот запрос, я получаю следующий вывод:

user_id | module_id | module_start_date | module_end_date | loading
-------------------------------------------------------------------    
6       | 3         | 01-01-2013        | 31-01-2013      | 0.4
6       | 4         | 15-02-2013        | 28-02-2013      | 0.2
6       | 5         | 01-03-2013        | 15-03-2013      | 0.7
6       | 3         | 30-01-2013        | 30-01-2013      | 0.5

Если вы внимательно посмотрите на результат, вы будете наблюдать, что пользователь на 100% доступен в дате 01-02-2013 до 14-02-2013 , то есть его загрузка равна 1.

// исправлены даты в приведенном выше предложении.

Я хочу, чтобы результат был следующим

user_id | module_id | module_start_date | module_end_date | loading
-------------------------------------------------------------------
6       | 3         | 30-01-2013        | 30-01-2013      | 0.5
6       | 3         | 01-01-2013        | 31-01-2013      | 0.4
6       | Null      | 01-02-2013        | 14-02-2013      | 1
6       | 4         | 15-02-2013        | 28-02-2013      | 0.2
6       | 5         | 01-03-2013        | 15-03-2013      | 0.7
6       | Null      | 16-03-2013        | 01-04-2013      | 1

У меня есть функция, которая дает мне дату с даты начала и окончания.

2
nl ja de
Вы отметили это как с mysql, так и с sql-сервером, какие rdbms вы используете?
добавлено автор Taryn, источник
sql server 2008
добавлено автор Sunil Harak, источник

1 ответы

Вы могли бы следовать этому подходу:

Слева присоединитесь к дням, которые у вас есть, со днями из функции таблицы даты в вашем диапазоне мин/макс. (Поскольку у вас уже есть функция таблицы даты, я опускаю этот код)

Скажем, у меня есть результаты за неделю 1 и неделю 3, когда я ушел, присоединившись к этим во все дни января, вы можете легко увидеть, где пробелы.

DECLARE @from DATETIME2(1) = '2013-01-01'
DECLARE @to DATETIME2(1) = '2013-01-31'

DECLARE @from_wk1 DATETIME2(1) = '2013-01-01'
DECLARE @to_wk1 DATETIME2(1) = '2013-01-07'

DECLARE @from_wk3 DATETIME2(1) = '2013-01-15'
DECLARE @to_wk3 DATETIME2(1) = '2013-01-22';

WITH    OccupiedDays ( [dt] )
          AS ( SELECT   B.[dt]
               FROM     DateTable(@from_wk1, @to_wk1) B
               UNION ALL
               SELECT   C.[dt]
               FROM     DateTable(@from_wk3, @to_wk3) C
             )
    SELECT  A.[dt]  AS AllDays,
            OD.[dt] AS OccupiedDays
    FROM    DateTable(@from, @to) A
            LEFT JOIN OccupiedDays OD ON A.[dt] = OD.[dt]

Результаты в:

sql output

Теперь вам нужно заполнить нулевые значения и сделать некоторые группировки и/или скопления.

0
добавлено
Проблема в том, что у меня есть много пользователей одновременно, и мне приходится группировать их вместе, а также их занятие изменится в лучшем случае
добавлено автор Sunil Harak, источник
SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)