这样的代码给我一个错误:“SQL错误[XX000]:错误:数字列2精度和比例无法合并”
WITH RECURSIVE build (PERIOD_START_DATE,PEQ,PREV_PEQ,repeated_patient, cur_rn, max_rn) as (
select
PERIOD_START_DATE,round(PEQ,1), round(cast(PREV_PEQ as float),1), round(cast(repeated_patient as float),1), cur_rn, max_rn from (
select
PERIOD_START_DATE,
PEQ,
cast(PREV_PEQ as float),
cast(repeated_patient as float),
ROW_NUMBER() OVER (ORDER BY period_start_date) AS rn
, 2::int as cur_rn
, count(1) over() as max_rn
from (select
PERIOD_START_DATE,
round(1.0*SU_VALUE /6, 1) PEQ,
LAG(ROUND(1.0*SU_VALUE/6,1 ),1) OVER ( ORDER BY PERIOD_START_DATE ) PREV_PEQ,
cast(0 as float) as repeated_patient
FROM testoss
) where PEQ != PREV_PEQ ) where rn=1
union all
select
b.PERIOD_START_DATE,
round(b.PEQ, 1),
round(b.PREV_PEQ, 1),
round(cast(case
when b.PREV_PEQ - nvl(t.repeated_patient,0) > b.PEQ then b.PEQ
else b.PREV_PEQ - nvl(t.repeated_patient,0)
end as float), 1) as repeated_patient,
b.cur_rn + 1 AS cur_rn,
b.max_rn
from build b join
(SELECT period_start_date, PEQ, PREV_PEQ, repeated_patient, lag(period_start_date) over(order by period_start_date) prev_period,
ROW_NUMBER() OVER (ORDER BY period_start_date) AS rn from (SELECT
PERIOD_START_DATE,
round(1.0*SU_VALUE /6, 1) PEQ,
LAG(ROUND(1.0*SU_VALUE/6,1 ),1) OVER (ORDER BY PERIOD_START_DATE ) PREV_PEQ,
cast(0 as float) as repeated_patient
FROM testoss
)) t ON t.prev_period = b.period_start_date
WHERE t.rn = b.cur_rn AND b.cur_rn <= b.max_rn)
select
PERIOD_START_DATE,
PEQ,
PREV_PEQ,
repeated_patient
from build;
给定周期日期 (PERIOD_START_DATE) 和标准单位值 (SU_VALUE),我需要编写以下要求:
• 剂量:在治疗的第1、2、13和14个月服用6片。第三年和第四年没有用药。
• 特定月份内服用该药物的患者总数的计算方法是将该月销售的标准单位 (SU) 除以每月剂量(视为 6 片 (SU))
• 当月新服药患者数按当月上述人数减去重复服药人数计算。一个月的重复患者相当于上个月的新患者。 ○ 我们假设新患者服用第二剂的依从性为 100%,因此计入接下来的 12 个月(下一步)
• 最终患者总数等于最近 12 个月的新患者数量,即当月(计算 TPE)和前 11 个月的新患者数量。
• 总患者等于份额的计算方法是将“使用上述方法计算的总患者等于”除以“所有 MS 产品的总患者等于之和”
这些应该是结果:
以上单元格中的要求和公式都在这里 ->
这是测试数据:
CREATE TABLE TESTOSS
( PERIOD_START_DATE, date,
SU integer
);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-SEP-17','DD-MON-RR'),69);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-OCT-17','DD-MON-RR'),263);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-NOV-17','DD-MON-RR'),684);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-DEC-17','DD-MON-RR'),938);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-JAN-18','DD-MON-RR'),1352);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-FEB-18','DD-MON-RR'),1174);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-MAR-18','DD-MON-RR'),1123);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-APR-18','DD-MON-RR'),1649);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-MAY-18','DD-MON-RR'),1402);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-JUN-18','DD-MON-RR'),1548);
Insert into TESTOSS (PERIOD_START_DATE,SU_VALUE) values (to_date('01-JUL-18','DD-MON-RR'),1448);
有人可以帮我解决吗?
对于 Oracle,使用 MODEL 子句解决了这个问题 将Excel公式翻译成SQL查询
WITH METRICS AS
(
SELECT
PERIOD_START_DATE,
PEQ,
PREV_PEQ,
REPEATED_PATIENT,
(PEQ - REPEATED_PATIENT) NEW_PATIENT
FROM
( SELECT PERIOD_START_DATE,
SU_VALUE /6 PEQ,
LAG (ROUND( SU_VALUE /6),1,0) OVER ( ORDER BY PERIOD_START_DATE ) REV_PEQ,
0 AS REPEATED_PATIENT
FROM TESTOSS
ORDER BY PERIOD_START_DATE
)
MODEL
DIMENSION BY (ROW_NUMBER() OVER (ORDER BY PERIOD_START_DATE) RN)
MEASURES (PRODUCT, PERIOD_START_DATE, PEQ, PREV_PEQ, REPEATED_PATIENT)
RULES (
REPEATED_PATIENT [ANY] =
(
CASE
WHEN PREV_PEQ[CV(RN)]-NVL(REPEATED_PATIENT[CV(RN)-1],0) > PEQ[CV(RN)] THEN PEQ[CV(RN)]
ELSE PREV_PEQ[CV(RN)]-NVL(REPEATED_PATIENT[CV(RN)-1],0)
END
)
)
)
SELECT
PERIOD_START_DATE,
NEW_PATIENT,
SUM(NEW_PATIENT) OVER(ORDER BY PERIOD_START_DATE RANGE BETWEEN INTERVAL '11' MONTH PRECEDING AND CURRENT ROW
) AS FINAL_PEQ
FROM METRICS
ORDER BY PERIOD_START_DATE
但是Redhsift中没有MODEL子句。
用 Redhsift 翻译了类似的案例 将 Excel 公式转换为 Redshift SQL 查询
您收到的错误是由于对不同类型的值进行 UNIONing 造成的。 “1.0*su_value /6”是不受控制范围的 NUMERIC 类型。 你需要照顾好你的类型。我认为当你在其他地方投射到此时你想要浮动。 这运行:
WITH recursive build (period_start_date,peq,prev_peq,repeated_patient, cur_rn, max_rn) AS
(
SELECT period_start_date,
round(peq,1),
round(cast(prev_peq AS FLOAT),1),
round(cast(repeated_patient AS FLOAT),1),
cur_rn,
max_rn
FROM (
SELECT period_start_date,
peq,
cast(prev_peq AS FLOAT),
cast(repeated_patient AS FLOAT),
row_number() over (ORDER BY period_start_date) AS rn ,
2::INT AS cur_rn ,
count(1) over() AS max_rn
FROM (
SELECT period_start_date,
round(1.0*su_value /6, 1)::float peq,
lag(round(1.0*su_value/6,1 ),1) over ( ORDER BY period_start_date )::float prev_peq,
cast(0 AS FLOAT) AS repeated_patient
FROM testoss
)
WHERE peq != prev_peq
)
WHERE rn=1
UNION ALL
SELECT b.period_start_date,
round(b.peq, 1),
round(b.prev_peq, 1),
round(cast(
CASE
WHEN b.prev_peq - nvl(t.repeated_patient,0) > b.peq THEN b.peq
ELSE b.prev_peq - nvl(t.repeated_patient,0)
END AS FLOAT), 1) AS repeated_patient,
b.cur_rn + 1 AS cur_rn,
b.max_rn
FROM build b
join
(
SELECT period_start_date,
peq,
prev_peq,
repeated_patient,
lag(period_start_date) over(ORDER BY period_start_date) prev_period,
row_number() over (ORDER BY period_start_date) AS rn
FROM (
SELECT period_start_date,
round(1.0*su_value /6, 1)::float peq,
lag(round(1.0*su_value/6,1 ),1) over (ORDER BY period_start_date )::float prev_peq,
cast(0 AS FLOAT) AS repeated_patient
FROM testoss )
) t
ON t.prev_period = b.period_start_date
WHERE t.rn = b.cur_rn
AND b.cur_rn <= b.max_rn
)
SELECT period_start_date,
peq,
prev_peq,
repeated_patient
FROM build;
此外,请在发布之前运行您的测试用例。 你有语法错误。