这个查询有什么问题。它在 TRUNCATE 上或附近给我语法错误
what is wrong in this query. It is giving me syntax error on or near TRUNCATE
我正在制作一个 postgresSql 函数来 return 来自临时 table 的所有行。我想在我的函数开始时删除 table 中的所有行但是它在 TRUNCATE 上或附近给我语法错误。
这是我的查询 -
CREATE OR REPLACE FUNCTION public.monthly_data_of_antenatal_care(hospitalId integer)
RETURNS SETOF antenatal_care_temp AS $$
SELECT DISTINCT * FROM antenatal_care_temp group by hospital_id,antenatal_temp_id;
BEGIN
TRUNCATE TABLE antenatal_care_temp RESTART IDENTITY;
FOR
select hospital_id from mas_hospital where parent_institute_id = or hospital_id =
LOOP
RETURN QUERY EXECUTE
'insert into table antenatal_care_temp(total,bpl,sc,st,below_19,jsy_reg,early_reg,high_risk_an,prophylaxis_i,prophylaxis_c1,prophylaxis_c2,treatment_i,
treatment_c1,treatment_c2,an_checkups_1,an_checkups_2,an_checkups_3,an_checkups_4,an_checkups_5,tt_a_1,tt_i_1,tt_a_2,tt_i_2,data_type) values(
(select count(*) from ph_anc_survey where Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
(select count(*) from ph_anc_survey where bpl_status = 'Y' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey where jsy_flag = 'Yes' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,
(select count(*) from ph_anc_survey where complication != '' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,0,0
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = )
'current',
);
insert into table antenatal_care_temp(total,bpl,sc,st,below_19,jsy_reg,early_reg,high_risk_an,prophylaxis_i,prophylaxis_c1,prophylaxis_c2,treatment_i,
treatment_c1,treatment_c2,an_checkups_1,an_checkups_2,an_checkups_3,an_checkups_4,an_checkups_5,tt_a_1,tt_i_1,tt_a_2,tt_i_2,data_type) values(
(select count(*) from ph_anc_survey where Extract(month from reg_date) between 4 and Extract(month from now()) and hospital_id = ),
(select count(*) from ph_anc_survey where bpl_status = 'Y' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey where jsy_flag = 'Yes' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,
(select count(*) from ph_anc_survey where complication != '' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,0,0
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = )
'cumulative',
)';
END LOOP;
END
$$ LANGUAGE sql;
你的函数有太多错误以至于很难知道从哪里开始。也不可能给你一个正确的解决方案,因为你的 INSERT
语句比 VALUES
子句有更多的列。
一些基本点:
- 学习PL/pgSQL。这应该可以解决许多语法问题,例如
BEGIN
. 之前的 SELECT
语句
- 如果您的函数
RETURNS SETOF something
您不需要先填充临时 table。最好你应该RETURN SETOF something
,当要返回的数据(可能)非常大时使用临时table,但是你会指定RETURNS void
(或者可能是临时table姓名)。但是,如果你完全摆脱临时 table 你应该指定 RETURNS TABLE (f1 int, f2 int, ...)
.
- 在函数体中,尽可能多地从循环中取出计算。
- 不要创建您自己不再理解的庞大
INSERT
声明,这会降低您的表现(在两个 INSERT
声明中,您使用相同的子项生成了 14 次数字查询!)。将其分解成可管理的块。
您应该生成一个看起来像这样的函数:
CREATE OR REPLACE FUNCTION public.monthly_data_of_antenatal_care(hospitalId integer)
RETURNS TABLE (total int, bpl int, sc int, st int, below_19 int, ....) AS $$
DECLARE
hid integer;
this_month timestamp;
cnt integer;
fup integer;
BEGIN
this_month = date_trunc('month', now()); -- Outside of the loop
FOR hid IN
SELECT hospital_id FROM mas_hospital
WHERE parent_institute_id = OR hospital_id =
LOOP
SELECT count(*) INTO cnt
FROM ph_anc_survey
WHERE date_trunc('month', reg_date) = this_month AND hospital_id = hid;
SELECT count(*) INTO fup
FROM ph_anc_survey pas JOIN ph_anc_followup paf USING (anc_reg_id)
WHERE paf.age < 19 AND date_trunc('month', paf.followup_date) = this_month
AND pas.hospital_id = hid;
-- More statements like above
RETURN NEXT VALUES (cnt, fup, 0, ...); -- Must match structure of RETURNS TABLE
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
我正在制作一个 postgresSql 函数来 return 来自临时 table 的所有行。我想在我的函数开始时删除 table 中的所有行但是它在 TRUNCATE 上或附近给我语法错误。 这是我的查询 -
CREATE OR REPLACE FUNCTION public.monthly_data_of_antenatal_care(hospitalId integer)
RETURNS SETOF antenatal_care_temp AS $$
SELECT DISTINCT * FROM antenatal_care_temp group by hospital_id,antenatal_temp_id;
BEGIN
TRUNCATE TABLE antenatal_care_temp RESTART IDENTITY;
FOR
select hospital_id from mas_hospital where parent_institute_id = or hospital_id =
LOOP
RETURN QUERY EXECUTE
'insert into table antenatal_care_temp(total,bpl,sc,st,below_19,jsy_reg,early_reg,high_risk_an,prophylaxis_i,prophylaxis_c1,prophylaxis_c2,treatment_i,
treatment_c1,treatment_c2,an_checkups_1,an_checkups_2,an_checkups_3,an_checkups_4,an_checkups_5,tt_a_1,tt_i_1,tt_a_2,tt_i_2,data_type) values(
(select count(*) from ph_anc_survey where Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
(select count(*) from ph_anc_survey where bpl_status = 'Y' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey where jsy_flag = 'Yes' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,
(select count(*) from ph_anc_survey where complication != '' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,0,0
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = ),
0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = )
'current',
);
insert into table antenatal_care_temp(total,bpl,sc,st,below_19,jsy_reg,early_reg,high_risk_an,prophylaxis_i,prophylaxis_c1,prophylaxis_c2,treatment_i,
treatment_c1,treatment_c2,an_checkups_1,an_checkups_2,an_checkups_3,an_checkups_4,an_checkups_5,tt_a_1,tt_i_1,tt_a_2,tt_i_2,data_type) values(
(select count(*) from ph_anc_survey where Extract(month from reg_date) between 4 and Extract(month from now()) and hospital_id = ),
(select count(*) from ph_anc_survey where bpl_status = 'Y' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey where jsy_flag = 'Yes' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,
(select count(*) from ph_anc_survey where complication != '' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = ),
0,0,0
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = ),
0,
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = )
'cumulative',
)';
END LOOP;
END
$$ LANGUAGE sql;
你的函数有太多错误以至于很难知道从哪里开始。也不可能给你一个正确的解决方案,因为你的 INSERT
语句比 VALUES
子句有更多的列。
一些基本点:
- 学习PL/pgSQL。这应该可以解决许多语法问题,例如
BEGIN
. 之前的 - 如果您的函数
RETURNS SETOF something
您不需要先填充临时 table。最好你应该RETURN SETOF something
,当要返回的数据(可能)非常大时使用临时table,但是你会指定RETURNS void
(或者可能是临时table姓名)。但是,如果你完全摆脱临时 table 你应该指定RETURNS TABLE (f1 int, f2 int, ...)
. - 在函数体中,尽可能多地从循环中取出计算。
- 不要创建您自己不再理解的庞大
INSERT
声明,这会降低您的表现(在两个INSERT
声明中,您使用相同的子项生成了 14 次数字查询!)。将其分解成可管理的块。
SELECT
语句
您应该生成一个看起来像这样的函数:
CREATE OR REPLACE FUNCTION public.monthly_data_of_antenatal_care(hospitalId integer)
RETURNS TABLE (total int, bpl int, sc int, st int, below_19 int, ....) AS $$
DECLARE
hid integer;
this_month timestamp;
cnt integer;
fup integer;
BEGIN
this_month = date_trunc('month', now()); -- Outside of the loop
FOR hid IN
SELECT hospital_id FROM mas_hospital
WHERE parent_institute_id = OR hospital_id =
LOOP
SELECT count(*) INTO cnt
FROM ph_anc_survey
WHERE date_trunc('month', reg_date) = this_month AND hospital_id = hid;
SELECT count(*) INTO fup
FROM ph_anc_survey pas JOIN ph_anc_followup paf USING (anc_reg_id)
WHERE paf.age < 19 AND date_trunc('month', paf.followup_date) = this_month
AND pas.hospital_id = hid;
-- More statements like above
RETURN NEXT VALUES (cnt, fup, 0, ...); -- Must match structure of RETURNS TABLE
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;