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