Использование поля даты для сопоставления SQL-запроса

У меня возникла небольшая проблема с логикой этого меняющегося измерения. Я хотел бы связать эти две таблицы ниже. Мне нужно сопоставить таблицу фактов «Стоимость — период» с измерением стоимости на основе идентификатора и даты вступления в силу.

Как видите, если поле месяца и года больше, чем дата вступления в силу связанного с ним измерения затрат, оно должно принять это значение. После того, как в измерение будет введена новая Дата вступления в силу, оно должно использовать это значение для любого периода, превышающего указанную дату в будущем.

РЕДАКТИРОВАНИЕ: приношу извинения за отсутствие подробностей, но измерение стоимости на самом деле будет иметь уникальное значение индекса, а изменяющиеся поля для ссылки на сопоставление будут Ресурс, Проект, Стоимость. Я попытался сопоставить запрос, который вы предоставили, с моими полями, но я получаю неверный результат.

К вашему сведению: изменение соглашения об именах: EngagementId — это Id, Resource — ConsultantId, а Project — ProjectId.

Я изменил изображения ниже, и вот мой запрос

     ,_cte(HoursWorked, HoursBilled, Month, Year, EngagementId, ConsultantId, ConsultantName, ProjectId, ProjectName, ProjectRetainer, RoleId, Role, Rate, ConsultantRetainer, Salary,  amount, EffectiveDate)
     as
     (
     select sum(t.Duration), 0, Month(t.StartDate), Year(t.StartDate),   t.EngagementId, c.ConsultantId, c.ConsultantName, c.ProjectId, c.ProjectName, c.ProjectRetainer, c.RoleId, c.Role, c.Rate, c.ConsultantRetainer, 
c.Salary, 0, c.EffectiveDate
      from timesheet t
      left join Engagement c on t.EngagementId = c.EngagementId and Month(c.EffectiveDate) = Month(t.EndDate) and Year(c.EffectiveDate) = Year(t.EndDate)
      group by Month(t.StartDate), Year(t.StartDate), t.EngagementId, c.ConsultantName, c.ConsultantId, c.ProjectId, c.ProjectName, c.ProjectRetainer, c.RoleId, c.Role, c.Rate, c.ConsultantRetainer, 
c.Salary, c.EffectiveDate

    )
    select * from _cte where EffectiveDate is not null
    union
    select _cte.HoursWorked, _cte.HoursBilled, _cte.Month, _cte.Year,  _cte.EngagementId, _cte.ConsultantId, _cte.ConsultantName, _cte.ProjectId, _Cte.ProjectName, _cte.ProjectRetainer, _cte.RoleId, _cte.Role, sub.Rate, _cte.ConsultantRetainer,_cte.Salary, _cte.amount, sub.EffectiveDate 
        from _cte
        outer apply (
                select top 1 EffectiveDate, Rate
                from Engagement e
                where e.ConsultantId = _cte.ConsultantId and e.ProjectId = _cte.ProjectId and e.RoleId = _cte.RoleId
                and Month(e.EffectiveDate) < _cte.Month and Year(e.EffectiveDate) < _cte.Year
                order by EffectiveDate desc
            ) sub
    where _cte.EffectiveDate is null

Пример:

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения

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

Это то, что можно выполнить в запросе, или мне следует сосредоточиться на добавочных обновлениях целевой таблицы, чтобы любой эффективный период даты/времени в прошлом оставался в покое?

Любые советы были бы замечательными!

Спасибо, Ченнинг.


person Channing    schedule 13.09.2016    source источник
comment
Нам нужно будет увидеть DDL вовлеченных таблиц (и предпочтительно тестовых данных) и столбцов, задействованных в SCD.   -  person NickyvV    schedule 14.09.2016
comment
В SCD задействованы следующие столбцы: ConsultantId, ProjectId и RateId. Постоянно меняющееся поле — RateId. После назначения новой ставки формируется новый EngagementId. Затем мы сопоставляем эту новую композицию с ее аналогами ConsultantId и ProjectId в зависимости от месяца и года. Дата вступления в силу формируется при создании новой ставки. То есть для каждого месяца года после этой даты вступления в силу она должна совпадать с новым Консультантом, Проектом и Ставкой. Должны ли мы игнорировать задание, поскольку оно больше связано с консультантом, проектом и ставкой? Создавать компенсационный ключ Консультанта, Проекта и Ставки?   -  person Channing    schedule 14.09.2016


Ответы (1)


Попробуй это:

; with _CTE as(
    select p.* , c.EffectiveDate, c.Cost
    from period p
      left join CostDimension c on p.id = c.id and p.Month = DATEPART(month, c.EffectiveDate) and p.year = DATEPART (year, EffectiveDate)
)
select * from _CTE Where EffectiveDate is not null

Union

select _CTE.id, _CTE.Month, _CTE.Year, sub.EffectiveDate, sub.Cost
from _CTE 
     outer apply (select top 1 EffectiveDate, Cost 
                  from CostDimension as cd
                  where cd.Id = _CTE.id and cd.EffectiveDate < DATETIMEFROMPARTS(_CTE.Year, _CTE.Month, 1, 0, 0, 0, 0) 
                  order by EffectiveDate desc
                  ) sub
where _Cte.EffectiveDate is null
person Sparrow    schedule 21.09.2016
comment
Я внес правку в пост, чтобы уточнить. Я присоединюсь к двум отдельным столам. Я хочу, чтобы присоединение учитывало изменение/даты и стоимость. Извините, если я был слишком расплывчатым! - person Channing; 22.09.2016
comment
Итак, просто для уточнения... «Стоимость - факт периода» — это ваш ожидаемый результат, а две другие таблицы — входные данные. Правильно? - person Sparrow; 22.09.2016
comment
Да, я присоединюсь к Периоду и Стоимость. После добавления каждой новой даты вступления в силу я хочу, чтобы все периоды с этого момента отражали соответствующую стоимость, сохраняя при этом стоимость любых периодов/изменений до этого. - person Channing; 22.09.2016
comment
Верны ли данные в таблице Period для Id = 2? Строки для идентификатора 2 относятся к месяцам 2 и 4, а даты вступления в силу в измерении затрат относятся к месяцам 1 и 3. Является ли это ошибкой или это действительно отражает реальный сценарий. - person Sparrow; 22.09.2016
comment
Это отражает сценарий. Обратите внимание, что при объединении таблиц затраты зависят от соответствующей даты вступления в силу. Поскольку 2 идет после 1, объединение дает нам стоимость 15. Как только период выходит за пределы месяца 3, он обновляет это значение до 20. Это должно быть логикой продвижения вперед для любых новых дополнительных затрат / дат вступления в силу. - person Channing; 22.09.2016
comment
Я изменил свой ответ. Попробуйте и дайте мне знать, если у вас есть какие-либо вопросы - person Sparrow; 22.09.2016
comment
Ваш ответ подвел меня так близко, но я чувствую, что это моя вина, что я не вдавался в подробности с несколькими полями. Я внес изменения в свой пост, если вы готовы обратиться к нему. - person Channing; 22.09.2016