I'm trying to expand on my understanding of CTE's and window partitions as used by PostgreSQL 9.1. (Example taken from my other question How to remove duplicate rows.) The situation is that cdesc
is a text field that (from a previous database) had unnecessary characters added to keep each cdesc
text entry different (and unique).
The problem is how to combine all entries in table CPT that match the string pattern of "excision/biopsy pathology".
Doing this fails since the "plan" is grouping the complete (and unique) cdesc
- not just the matching part:
WITH plan AS (
SELECT recid, cdesc, min(recid) OVER (PARTITION BY cdesc) AS master_recid
FROM cpt
WHERE cpt.cdesc LIKE '%excision/biopsy pathology%'
)
, upd_lab AS (
UPDATE lab l
SET cpt_recid = p.master_recid
FROM plan p
WHERE l.cpt_recid = p.recid
AND p.recid <> p.master_recid
)
DELETE FROM cpt c
USING plan p
WHERE c.cdesc LIKE '%excision/biopsy pathology%'
AND c.recid = p.recid
AND p.recid <> p.master_recid
RETURNING c.recid;
The lab
table is defined (from the previous question) as:
CREATE TABLE lab (
recid serial NOT NULL,
cpt_recid integer,
........
CONSTRAINT cs_cpt FOREIGN KEY (cpt_recid)
REFERENCES cpt (recid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE RESTRICT,
...
);
My questions are:
- How can string pattern matching be used with the partition, and
- How does the
upd_lab
update get called to move records in the lab table to the newmaster_recid
?
Edit #1:
The following DOES work to do what I need, but I'm still unclear as to how the upd_lab
cte is being called:
WITH plan AS (
SELECT recid, min(recid) OVER (PARTITION BY cdesc LIKE '%excision/biopsy pathology%') AS master_recid
FROM cpt
WHERE cpt.cdesc LIKE '%excision/biopsy pathology%'
)
, upd_lab AS (
UPDATE lab l
SET cpt_recid = p.master_recid -- link to master recid ...
FROM plan p
WHERE l.cpt_recid = p.recid
AND p.recid <> p.master_recid -- ... only if not linked to master
)
DELETE FROM cpt c
USING plan p
WHERE c.cdesc LIKE '%excision/biopsy pathology%'
AND c.recid = p.recid
AND p.recid <> p.master_recid -- ... only if notmaster
RETURNING c.recid;