--testing table
CREATE TABLE public.test_patient_table (
entity_id INTEGER NOT NULL,
site_held_at INTEGER NOT NULL,
CONSTRAINT entityid_pk PRIMARY KEY (entity_id)
);
CREATE TABLE public.test_messageq_table (
entity_id VARCHAR NOT NULL,
master_id INTEGER NOT NULL,
message_body VARCHAR NOT NULL,
CONSTRAINT mq_entity_id_pk PRIMARY KEY (entity_id)
);
CREATE INDEX test_patient_table_siteid_idx
ON public.test_patient_table
( site_held_at );
ALTER TABLE public.test_messageq_table
ADD CONSTRAINT test_patient_table_test_messageq_table_fk
FOREIGN KEY (master_id)
REFERENCES public.test_patient_table (entity_id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
--test patient data
insert into test_patient_table values (1, 11111);
insert into test_patient_table values (2, 11111);
insert into test_patient_table values (3, 11111);
insert into test_patient_table values (4, 11111);
insert into test_patient_table values (5, 22222);
insert into test_patient_table values (6, 22222);
insert into test_patient_table values (7, 22222);
insert into test_patient_table values (8, 22222);
insert into test_patient_table values (9, 33333);
insert into test_patient_table values (10, 33333);
insert into test_patient_table values (11, 44444);
--testing message
insert into test_messageq_table values (1, 1, 'aaa');
insert into test_messageq_table values (2, 1, 'aaa');
insert into test_messageq_table values (3, 1, 'aaa');
insert into test_messageq_table values (4, 1, 'aaa');
insert into test_messageq_table values (5, 2, 'aaa');
insert into test_messageq_table values (6, 2, 'aaa');
insert into test_messageq_table values (7, 5, 'aaa');
insert into test_messageq_table values (8, 8, 'aaa');
insert into test_messageq_table values (9, 11, 'aaa');
insert into test_messageq_table values (10, 11, 'bbb');
Als ich versucht habe, alle Nachrichten aus der Nachrichtentabelle in der Site zu finden, die mich interessiert, habe ich einen CTE geschrieben und er funktioniert einwandfrei. Nehmen wir an, ich interessiere mich für die Site 11111 und 22222:
WITH patient_msg_in_branches AS (
select distinct test_messageq_table.master_id AS patient_id,
test_patient_table.site_held_at as site_id
from test_messageq_table
inner join test_patient_table
ON test_messageq_table.master_id = test_patient_table.entity_id
and site_held_at in (11111,22222) order by patient_id
),
messages_for_patients AS(
select * from test_messageq_table where master_id in
(select patient_msg_in_branches.patient_id
from patient_msg_in_branches)
)select * from messages_for_patients
Das Ergebnis ist wie erwartet:
"1";1;"aaa"
"2";1;"aaa"
"3";1;"aaa"
"4";1;"aaa"
"5";2;"aaa"
"6";2;"aaa"
"7";5;"aaa"
"8";8;"aaa"
Aber wenn ich das Ganze in eine Funktion einbinde, werden die falschen Zeilen zurückgegeben. Kannst du mir helfen zu verstehen warum?
drop function getMessageFromSites(text);
CREATE OR REPLACE FUNCTION getMessageFromSites(IN ids TEXT) RETURNS
setof test_messageq_table AS $$
DECLARE
sites INT[];
result test_messageq_table%rowtype;
BEGIN
sites = string_to_array(ids,',');
raise info 'entire array: %', sites;
WITH patient_msg_in_branches AS (
select distinct test_messageq_table.master_id AS patient_id,
test_patient_table.site_held_at as site_id
from test_messageq_table
inner join test_patient_table
ON test_messageq_table.master_id = test_patient_table.entity_id
and site_held_at = ANY(sites) order by patient_id
),
messages_for_patients AS(
select * from test_messageq_table where master_id in
(select patient_msg_in_branches.patient_id
from patient_msg_in_branches)
)select * into result from messages_for_patients;
return query select * from result;
END;
$$ LANGUAGE plpgsql;
Bei Verwendung der Funktion:
select * from getMessageFromSites('11111,22222');
select * from getMessageFromSites('1')
select * from getMessageFromSites('33333')
es gibt immer das gleiche Ergebnis unterhalb mehrerer Zeilen aber offensichtlich falsch Zeilen, warum? kannst du hier helfen
"1";1;"aaa"
"2";1;"aaa"
"3";1;"aaa"
"4";1;"aaa"
"5";2;"aaa"
"6";2;"aaa"
"9";11;"aaa"
"10";11;"bbb"
Lösung
Dank @a_horse_with_no_name habe ich jetzt zwei funktionierende Lösungen, eine mit SQL, eine mit pl / pgsql:
Lösung 1 (pl / pgsql)
CREATE OR REPLACE FUNCTION getMessageFromSites(IN ids TEXT) RETURNS
setof test_messageq_table AS $$
DECLARE
sites INT[];
result test_messageq_table%rowtype;
BEGIN
sites = string_to_array(ids,',');
raise info 'entire array: %', sites;
return QUERY
WITH patient_msg_in_branches AS (
select distinct test_messageq_table.master_id AS patient_id,
test_patient_table.site_held_at as site_id
from test_messageq_table
inner join test_patient_table
ON test_messageq_table.master_id = test_patient_table.entity_id
and site_held_at = ANY(sites) order by patient_id
),
messages_for_patients AS(
select * from test_messageq_table where master_id in
(select patient_msg_in_branches.patient_id
from patient_msg_in_branches)
)
select * from messages_for_patients;
END;
$$ LANGUAGE plpgsql;
Lösung 2 (sql)
CREATE OR REPLACE FUNCTION getMessageFromSites2(ids TEXT) RETURNS
setof test_messageq_table
AS
$$
WITH patient_msg_in_branches AS (
select distinct test_messageq_table.master_id AS patient_id,
test_patient_table.site_held_at as site_id
from test_messageq_table
join test_patient_table ON test_messageq_table.master_id = test_patient_table.entity_id
and site_held_at = ANY (string_to_array($1,',')::int[])
),
messages_for_patients AS
(
select *
from test_messageq_table
where master_id in (select patient_msg_in_branches.patient_id
from patient_msg_in_branches)
)
select *
from messages_for_patients;
$$
LANGUAGE sql;
Testen des Codes
select * from getMessageFromSites('11111,44444');
select * from getMessageFromSites('22222');
select * from getMessageFromSites('1')
select * from getMessageFromSites('33333')
select * from getMessageFromSites2('11111');
select * from getMessageFromSites2('22222');
select * from getMessageFromSites2('33333');
select * from getMessageFromSites('44444,11111');
select * from getMessageFromSites('1');
Beide gespeicherten PG-Prozeduren funktionieren wie erwartet!
Lösung 3: Eine besser vereinfachte Lösung siehe Erwins Antwort unten.
Jetzt Fall geschlossen!