在 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,
 ...
);

我的问题是:

  1. 字符串模式匹配如何与分区一起使用,
  2. 如何调用 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 bywhere 正在做你想要的工作:

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;