У меня есть список индивидуальных подписчиков плана медицинского обслуживания. У каждого подписчика есть диапазон дат, чтобы указать право на участие в плане. Чтобы проиллюстрировать это, приведу примерный список записей для соответствующих критериям подписчиков за 2018-Q1, написанный на T-SQL для MS SQL Server:
-- qryEligibleSubscribers2018-Q1Simple
WITH
S
AS
(
-- MOCK LIST OF SUBSCRIBERS TO HEALTH PLAN
-- WITH ELIGIBILITY TIME FRAMES
SELECT
-- CONTINUOUSLY ELIGIBLE SINCE 2017
'0001' AS ID,
'MOUSE' AS LASTNAME,
'MICKEY' AS FIRSTNAME,
'1/1/2017' AS EFFECTIVE,
NULL AS TERM
UNION ALL SELECT
-- CURRENT SUBSCRIBER SINCE FEB. 2018
'0002' AS ID,
'MOUSE' AS LASTNAME,
'MINNIE' AS FIRSTNAME,
'2/1/2018' AS EFFECTIVE,
NULL AS TERM
UNION ALL SELECT
-- SUBSCRIBED TO PLAN FOR JAN. 2018 ONLY
'0003' AS ID,
'DUCK' AS LASTNAME,
'DONALD' AS FIRSTNAME,
'1/1/2018' AS EFFECTIVE,
'1/31/2018' AS TERM
UNION ALL SELECT
-- SUBSCRIBED TO PLAN STARTING IN 2018-Q2
'0004' AS ID,
'GOOF' AS LASTNAME,
'GOOFY' AS FIRSTNAME,
'4/1/2018' AS EFFECTIVE,
NULL AS TERM
)
-- LIST OF SUBSCRIBERS
-- WHO WERE ELIGIBLE IN 2018-Q1 ONLY
SELECT
S.ID,
S.LASTNAME,
S.FIRSTNAME,
S.EFFECTIVE,
S.TERM
FROM
S
WHERE
-- LIMIT LIST TO 2018-Q1
S.EFFECTIVE <= '3/31/2018'
AND
ISNULL(S.TERM,GETDATE()) >= '1/1/2018'
При запуске получаются три (из четырех) подписчика:
ID LASTNAME FIRSTNAME EFFECTIVE TERM
-----------------------------------------------------
0001 MOUSE MICKEY 1/1/2017
0002 MOUSE MINNIE 2/1/2018
0003 DUCK DONALD 1/1/2018 1/31/2018
-----------------------------------------------------
Мы можем видеть из результатов, что Микки Маус имел право на все три месяца на 2018-I квартал, Минни Маус имела право только на февраль и март, Дональд Дак имел право только на первый месяц квартала, и Гуфи пришел на к плану в 2018-Q2 и поэтому не включен в набор результатов.
Мне нужно отчитываться об общей численности подписчиков за каждый месяц. Я могу сделать это с помощью этого более сложного запроса, также написанного на T-SQL для MS-SQL Server:
-- qryEligibleSubscribers2018-Q1Complex
WITH
-- LIST OF MONTHS IN 2018-Q1
R(BOR,EOR)
AS
(
-- FIXED RANGE OF MONTHS IN 2018-Q1
SELECT
DATEADD(M,DATEDIFF(M,0,'1/1/2018'),0) AS BOR,
DATEADD(M,DATEDIFF(M,0,'3/31/2018'),0) AS EOR
-- RECURSIVELY ADD A MONTH
UNION ALL SELECT
DATEADD(M,1,R.BOR) AS BOR,
R.EOR
FROM
R
WHERE
R.BOR < R.EOR
),
S
AS
(
-- MOCK LIST OF SUBSCRIBERS TO HEALTH PLAN
-- WITH ELIGIBILITY TIME FRAMES
SELECT
-- CONTINUOUSLY ELIGIBLE SINCE 2017
'0001' AS ID,
'MOUSE' AS LASTNAME,
'MICKEY' AS FIRSTNAME,
'1/1/2017' AS EFFECTIVE,
NULL AS TERM
UNION ALL SELECT
-- CURRENT SUBSCRIBER SINCE FEB. 2018
'0002' AS ID,
'MOUSE' AS LASTNAME,
'MINNIE' AS FIRSTNAME,
'2/1/2018' AS EFFECTIVE,
NULL AS TERM
UNION ALL SELECT
-- SUBSCRIBED TO PLAN FOR JAN. 2018 ONLY
'0003' AS ID,
'DUCK' AS LASTNAME,
'DONALD' AS FIRSTNAME,
'1/1/2018' AS EFFECTIVE,
'1/31/2018' AS TERM
UNION ALL SELECT
-- SUBSCRIBED TO PLAN STARTING IN 2018-Q2
'0004' AS ID,
'GOOF' AS LASTNAME,
'GOOFY' AS FIRSTNAME,
'4/1/2018' AS EFFECTIVE,
NULL AS TERM
),
X
AS
(
-- EXTENDED LIST OF SUBSCRIBERS
-- WHO WERE ELIGIBLE IN 2018-Q1 ONLY
-- LISTING EACH MONTH OF ELIGIBILITY
SELECT
R.BOR AS MONTH,
FORMAT(R.BOR,'MMMM yyyy') AS LABEL,
S.ID,
S.LASTNAME,
S.FIRSTNAME,
S.EFFECTIVE,
S.TERM
FROM
S
INNER JOIN
R
ON
S.EFFECTIVE < DATEADD(M,1,R.BOR)
AND
ISNULL(S.TERM,GETDATE()) >= R.BOR
)
SELECT
X.LABEL AS MONTH,
COUNT(X.ID) AS TOTAL
FROM
X
GROUP BY
X.LABEL,
X.MONTH
ORDER BY
X.MONTH
Результаты, полученные при запуске, показывают, что в каждом квартале в 1-м квартале в общей сложности имелось два подписчика:
MONTH TOTAL
-----------------
January 2018 2
February 2018 2
March 2018 2
-----------------
Чтобы увидеть подробные / неагрегированные результаты - в частности, какой подписчик имел право в течение каких месяцев, мы можем выполнить этот запрос (также написанный на T-SQL для MS-SQL Server):
-- qryEligibleSubscribers2018-Q1Detailed
WITH
-- LIST OF MONTHS IN 2018-Q1
R(BOR,EOR)
AS
(
-- FIXED RANGE OF MONTHS IN 2018-Q1
SELECT
DATEADD(M,DATEDIFF(M,0,'1/1/2018'),0) AS BOR,
DATEADD(M,DATEDIFF(M,0,'3/31/2018'),0) AS EOR
-- RECURSIVELY ADD A MONTH
UNION ALL SELECT
DATEADD(M,1,R.BOR) AS BOR,
R.EOR
FROM
R
WHERE
R.BOR < R.EOR
),
S
AS
(
-- MOCK LIST OF SUBSCRIBERS TO HEALTH PLAN
-- WITH ELIGIBILITY TIME FRAMES
SELECT
-- CONTINUOUSLY ELIGIBLE SINCE 2017
'0001' AS ID,
'MOUSE' AS LASTNAME,
'MICKEY' AS FIRSTNAME,
'1/1/2017' AS EFFECTIVE,
NULL AS TERM
UNION ALL SELECT
-- CURRENT SUBSCRIBER SINCE FEB. 2018
'0002' AS ID,
'MOUSE' AS LASTNAME,
'MINNIE' AS FIRSTNAME,
'2/1/2018' AS EFFECTIVE,
NULL AS TERM
UNION ALL SELECT
-- SUBSCRIBED TO PLAN FOR JAN. 2018 ONLY
'0003' AS ID,
'DUCK' AS LASTNAME,
'DONALD' AS FIRSTNAME,
'1/1/2018' AS EFFECTIVE,
'1/31/2018' AS TERM
UNION ALL SELECT
-- SUBSCRIBED TO PLAN STARTING IN 2018-Q2
'0004' AS ID,
'GOOF' AS LASTNAME,
'GOOFY' AS FIRSTNAME,
'4/1/2018' AS EFFECTIVE,
NULL AS TERM
)
-- EXTENDED LIST OF SUBSCRIBERS
-- WHO WERE ELIGIBLE IN 2018-Q1 ONLY
-- LISTING EACH MONTH OF ELIGIBILITY
SELECT
FORMAT(R.BOR,'MMMM yyyy') AS LABEL,
S.ID,
S.LASTNAME,
S.FIRSTNAME,
S.EFFECTIVE,
S.TERM
FROM
S
INNER JOIN
R
ON
S.EFFECTIVE < DATEADD(M,1,R.BOR)
AND
ISNULL(S.TERM,GETDATE()) >= R.BOR
ORDER BY
R.BOR,
S.ID
Подробные помесячные результаты:
MONTH ID LASTNAME FIRSTNAME EFFECTIVE TERM
---------------------------------------------------------------------
January 2018 0001 MOUSE MICKEY 1/1/2017
January 2018 0003 DUCK DONALD 1/1/2018 1/31/2018
February 2018 0001 MOUSE MICKEY 1/1/2017
February 2018 0002 MOUSE MINNIE 2/1/2018
March 2018 0001 MOUSE MICKEY 1/1/2017
March 2018 0002 MOUSE MINNIE 2/1/2018
---------------------------------------------------------------------
При исходном простом запросе результирующий набор доставляет три записи, по одной для каждого подходящего подписчика за весь интересующий диапазон дат (2018-Q1.)
ID LASTNAME FIRSTNAME EFFECTIVE TERM
-----------------------------------------------------
0001 MOUSE MICKEY 1/1/2017
0002 MOUSE MINNIE 2/1/2018
0003 DUCK DONALD 1/1/2018 1/31/2018
-----------------------------------------------------
При более сложном и подробном запросе набор результатов доставляет шесть записей, по одной на каждый месяц, в течение которого подписчик имел право на этот конкретный месяц в интересующем квартале.
MONTH ID LASTNAME FIRSTNAME EFFECTIVE TERM
---------------------------------------------------------------------
January 2018 0001 MOUSE MICKEY 1/1/2017
January 2018 0003 DUCK DONALD 1/1/2018 1/31/2018
February 2018 0001 MOUSE MICKEY 1/1/2017
February 2018 0002 MOUSE MINNIE 2/1/2018
March 2018 0001 MOUSE MICKEY 1/1/2017
March 2018 0002 MOUSE MINNIE 2/1/2018
---------------------------------------------------------------------
На практике у нас несколько сотен тысяч подписчиков. Чтобы использовать более сложный запрос, получается громоздкий набор результатов (например, за 12-месячный период каждая из сотен тысяч записей может быть умножена до 12 раз ... по одной на каждый месяц.) Мне нужно сохранить мой простой запрос как двигатель, который управляет моим отчетом SSRS. Используя простой набор результатов ...:
ID LASTNAME FIRSTNAME EFFECTIVE TERM
-----------------------------------------------------
0001 MOUSE MICKEY 1/1/2017
0002 MOUSE MINNIE 2/1/2018
0003 DUCK DONALD 1/1/2018 1/31/2018
-----------------------------------------------------
... Кажется, я не могу понять, как в SSRS создать отчет, который будет обеспечивать ежемесячное совокупное число подписчиков. Другими словами, мне нужно и нужно, чтобы службы отчетов SSRS выполняли работу по умножению / разделению / дублированию записей на соответствующие приемлемые месяцы, а не на базовый запрос SQL:
MONTH TOTAL
-----------------
January 2018 2
February 2018 2
March 2018 2
-----------------
Суть проблемы состоит в том, чтобы выяснить, если это вообще возможно, как разделить и сгруппировать диапазон дат в SSRS, как я делаю в более сложных запросах SQL.
Я пытался использовать различные варианты Lookup () в построителе отчетов, но для этого требуется соответствие один к одному, например, MultiLookup () извлекает набор значений из набора данных для пар имя-значение, где каждый пара имеет отношение 1 к 1.
В моем примере определенный месяц в квартале должен совпадать с конкретным месяцем (в диапазоне месяцев) в наборе подписчиков. Здесь, как мы видим из простого запроса, подписчик может иметь право на участие в течение нескольких месяцев. Я полагаю, что смог бы успешно построить отчет SSRS в построителе отчетов, если бы существовал некоторый вариант Lookup (), который включал наличие определенного ключа в одном наборе данных (например, январь 2018 года) в пределах диапазона ключей в другом наборе данных (август 2016 года). - май 2018), в отличие от точного матча 1: 1.
Формат результатов не имеет значения. Может быть диаграмма или таблица. Просто хочу получить результаты, если возможно, пока.