在 PostgreSQL 中难以使用 CTE 与 window PARTITION BY 和字符串模式匹配
Difficulty using CTE's with window PARTITION BY and string pattern matching in PostgreSQL
我正在尝试扩展我对 PostgreSQL 9.1 使用的 CTE 和 window 分区的理解。 (示例取自我的另一个问题 。)情况是 cdesc
是一个文本字段(来自以前的数据库)添加了不必要的字符以保持每个 cdesc
文本条目不同(和独特)。
The problem is how to combine all entries in table CPT that match the string pattern of "excision/biopsy pathology".
这样做失败,因为 "plan" 正在对完整(且唯一)的 cdesc
进行分组 - 而不仅仅是匹配部分:
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;
lab
table 定义(来自上一个问题)为:
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,
...
);
我的问题是:
- 字符串模式匹配如何与分区一起使用,
- 如何调用
upd_lab
更新将实验室 table 中的记录移动到新的 master_recid
?
编辑#1:
以下确实可以满足我的需要,但我仍然不清楚 upd_lab
cte 是如何被调用的:
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;
只需删除 partition by
。 where
正在做你想要的工作:
WITH plan AS (
SELECT recid, cdesc, min(recid) OVER () 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;
我正在尝试扩展我对 PostgreSQL 9.1 使用的 CTE 和 window 分区的理解。 (示例取自我的另一个问题 cdesc
是一个文本字段(来自以前的数据库)添加了不必要的字符以保持每个 cdesc
文本条目不同(和独特)。
The problem is how to combine all entries in table CPT that match the string pattern of "excision/biopsy pathology".
这样做失败,因为 "plan" 正在对完整(且唯一)的 cdesc
进行分组 - 而不仅仅是匹配部分:
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;
lab
table 定义(来自上一个问题)为:
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,
...
);
我的问题是:
- 字符串模式匹配如何与分区一起使用,
- 如何调用
upd_lab
更新将实验室 table 中的记录移动到新的master_recid
?
编辑#1:
以下确实可以满足我的需要,但我仍然不清楚 upd_lab
cte 是如何被调用的:
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;
只需删除 partition by
。 where
正在做你想要的工作:
WITH plan AS (
SELECT recid, cdesc, min(recid) OVER () 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;