Как сгруппировать по диапазону дат в построителе отчетов SSRS? - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть список индивидуальных подписчиков плана медицинского обслуживания. У каждого подписчика есть диапазон дат, чтобы указать право на участие в плане. Чтобы проиллюстрировать это, приведу примерный список записей для соответствующих критериям подписчиков за 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.

Формат результатов не имеет значения. Может быть диаграмма или таблица. Просто хочу получить результаты, если возможно, пока.

1 Ответ

0 голосов
/ 30 апреля 2018

Нет - к сожалению, я не могу придумать простой способ для SSRS сгруппировать по месяцам и рассчитать каждый, как вам нужно.

Если вы просто хотите избежать запуска нескольких запросов, то для вашей ситуации может пригодиться временная таблица .

Ваш первый набор данных поместит подробные данные во временную таблицу и ВЫБЕРИ детали из таблицы.

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

Установите флажок Использовать одну транзакцию в свойствах ИСТОЧНИК ДАННЫХ , чтобы сохранить временную таблицу.

...