Hive оконный запрос - PullRequest
       9

Hive оконный запрос

0 голосов
/ 26 октября 2018

У меня есть базовая таблица Hive со следующей схемой: This is my base table

И я хочу следующий вывод: This is the desired output

Таким образом, в основном группировка по всем столбцам и вычисление количества отдельных встреч в этом месяце и за последние 3 месяца (включая этот месяц). Например, для DischargeMonthYear Jan-2018 , num_discharges_last_30_days будут выписаны пациенты в январе-2018 (3), а num_discharges_last_90_days будут выписаны пациенты в ноябре-17, 17 декабря и 18 января. Поскольку в этом случае данных до 18 января в этом случае нет, оба показателя будут одинаковыми. Аналогично для 18 марта, num_discharges_last_90_days должен включать в себя счет за январь, февраль и 18 марта (3 + 2 + 2 = 7). Для 18 июня, поскольку у нас нет данных за апрель и 18 мая, он должен включать подсчеты только за 18 июня и НЕ попадать в предыдущую группу / раздел.

У меня есть запрос ниже, который дает мне правильную сумму за num_discharges_last_90_days до 18 июня, но не соответствует группировке более ранних столбцов, а для 18 июля он также включает итоги 18 июня, которые не должны быть так, поскольку регион отличается.

Если я добавлю для него предложение PARTITION BY region (и другие), num_discharges_last_90_days будет правильным для 18 июля, но неверным для 18 июня, поскольку включает итоги за февраль и 18 марта.

`

DROP TABLE IF EXISTS Encounter;
CREATE TEMPORARY TABLE Encounter
(
       Encounter_no int,
       Admit_date date,
       discharge_date date,
       region varchar(50),
       Facilityname varchar(50),
       Payertype varchar(10),
       Payernamme varchar(20),
       patient_type varchar(10)
);

INSERT INTO Encounter
select 12345, '2018-01-01', '2018-01-05', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12346, '2018-01-02', '2018-01-06', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12347, '2018-01-03', '2018-01-07', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12348, '2018-02-04', '2018-02-08', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12349, '2018-02-05', '2018-02-09', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12350, '2018-03-06', '2018-03-10', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12351, '2018-03-07', '2018-03-11', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12352, '2018-06-08', '2018-06-12', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12353, '2018-06-09', '2018-06-13', 'Midwest', 'ABC', 'MCR', 'MCR123', 'IP' union all
select 12354, '2018-07-10', '2018-07-14', 'NorthEast', 'ABC', 'MCR', 'MCR123', 'IP'
;
--SELECT from_unixtime(unix_timestamp(e.discharge_date, 'yyyy-MM-dd'),'MM') AS `Discharge_Month` FROM Encounter e

--Below CTE is used to get all month numbers
WITH R AS
(
    SELECT '01' AS MonthNum
    UNION ALL SELECT '02'
    UNION ALL SELECT '03'
    UNION ALL SELECT '04'
    UNION ALL SELECT '05'
    UNION ALL SELECT '06'
    UNION ALL SELECT '07'
    UNION ALL SELECT '08'
    UNION ALL SELECT '09'
    UNION ALL SELECT '10'
    UNION ALL SELECT '11'
    UNION ALL SELECT '12'
)
SELECT *  FROM
(
    --Perform a left join on CTE with your query to get all months
    SELECT 
    R.MonthNum,
    e.region,
    e.facilityname,
    from_unixtime(unix_timestamp(e.discharge_date, 'yyyy-MM-dd'),'MMM-yyyy') AS Discharge_Month,
    e.Payertype,
    e.Payernamme,
    e.patient_type,
    CASE WHEN COALESCE(e.region, '') <> ''
        THEN COUNT(1)  
        ELSE 0
    END
    as num_discharges_last_30_days,
    SUM(
        CASE WHEN COALESCE(e.region, '') <> '' 
        THEN COUNT(1)  
        ELSE 0
        END
        )
         OVER (ORDER BY R.MonthNum
               ROWS BETWEEN 2 PRECEDING AND CURRENT ROW 
               ) as num_discharges_last_90_days
    FROM R
    LEFT JOIN Encounter e
        ON R.MonthNum = from_unixtime(unix_timestamp(e.discharge_date, 'yyyy-MM-dd'),'MM')
    GROUP BY 
    R.MonthNum,
    e.region,
    e.facilityname,
    from_unixtime(unix_timestamp(e.discharge_date, 'yyyy-MM-dd'),'MMM-yyyy'),
    e.Payertype,
    e.Payernamme,
    e.patient_type
) A
WHERE A.region IS NOT NULL
;

`

1 Ответ

0 голосов
/ 01 ноября 2018

Мой коллега взломал вопрос, используя следующий запрос. Для подсчета вычислений за последние 3 месяца потребовалось самостоятельное объединение и предложения CASE & WHERE.

WITH CTE AS (
    SELECT a.region,a.facilityname,a.payertype,a.payernamme,a.patient_type, LAST_DAY(a.discharge_date) AS month_year, COUNT(encounter_no) AS measure_1
    FROM Encounter AS a
    GROUP BY a.region,a.facilityname,a.payertype,a.payernamme,a.patient_type, LAST_DAY(a.discharge_date)
)
-- SELECT * FROM CTE AS a;
SELECT a.region,a.facilityname,a.payertype,a.payernamme,a.patient_type, a.month_year, MAX(a.measure_1) AS measure_1,
    SUM(IF(b.month_year IS NULL, a.measure_1, b.measure_1)) AS measure_2
FROM CTE AS a
    LEFT JOIN CTE AS b
        ON a.region = b.region
        AND a.facilityname = b.facilityname
        AND a.payertype = b.payertype
        AND a.payernamme = b.payernamme
        AND a.patient_type = b.patient_type
WHERE ( b.month_year BETWEEN add_months(a.month_year, -2) AND a.month_year
        OR b.month_year IS NULL)
GROUP BY a.region,a.facilityname,a.payertype,a.payernamme,a.patient_type, a.month_year;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...