Для части 1 сделайте это так:
with t as (
select 1 individual, cast('20181210' as date) date, 'A' clinic union all
select 1 individual, cast('20190305' as date) date, 'A' clinic union all
select 1 individual, cast('20190831' as date) date, 'A' clinic union all
select 2 individual, cast('20181202' as date) date, 'A' clinic union all
select 2 individual, cast('20190316' as date) date, 'A' clinic union all
select 2 individual, cast('20190412' as date) date, 'A' clinic union all
select 2 individual, cast('20190516' as date) date, 'A' clinic union all
select 3 individual, cast('20181207' as date) date, 'B' clinic union all
select 3 individual, cast('20190512' as date) date, 'B' clinic union all
select 3 individual, cast('20190619' as date) date, 'B' clinic
), t1 as (
select *, cast(datepart(year, date) as char(4)) + cast(datepart(week, date) as char(2)) yearweek from t
)
select count(distinct date) cnt, individual, yearweek from t1 group by individual, yearweek
Он создает столбец yearweek
, который использует datepart
, чтобы иметь возможность группировать по неделям.
Теперь я можно создать весь список с аналитическими функциями вместо группировки по. Есть небольшая проблема, потому что Microsoft Sql не разрешает count(distinct column) over (partition by ...)
- я использую обходной путь для этого, используя дважды dense_rank() over (...)
. Я также добавил столбец начала недели и столбца конца недели. Как и раньше, я использую CTE, чтобы сначала создать данные примера, а затем выполнить требуемые изменения:
with t as (
select 1 individual, cast('20181210' as date) date, 'A' clinic union all
select 1 individual, cast('20190305' as date) date, 'A' clinic union all
select 1 individual, cast('20190831' as date) date, 'A' clinic union all
select 2 individual, cast('20181202' as date) date, 'A' clinic union all
select 2 individual, cast('20190316' as date) date, 'A' clinic union all
select 2 individual, cast('20190412' as date) date, 'A' clinic union all
select 2 individual, cast('20190516' as date) date, 'A' clinic union all
select 2 individual, cast('20190514' as date) date, 'A' clinic union all--new row to demonstrate count-distinct
select 3 individual, cast('20181207' as date) date, 'B' clinic union all
select 3 individual, cast('20190512' as date) date, 'B' clinic union all
select 3 individual, cast('20190619' as date) date, 'B' clinic
), t1 as (
select *, cast(datepart(year, date) as char(4)) + cast(datepart(week, date) as char(2)) yearweek,
dateadd(day, -((5 + DATEPART(dw, date) + @@DATEFIRST) % 7), date) start_of_week,
dateadd(day, 7-((5 + DATEPART(dw, date) + @@DATEFIRST) % 7), date) end_of_week
from t
)
select dense_rank() over (partition by individual, yearweek order by date) + dense_rank() over (partition by individual, yearweek order by date desc) - 1 cnt_distinct,
individual, yearweek, start_of_week, date, end_of_week
from t1
order by yearweek, individual