2015-06-27 21 views
1

我试图扩展对PostgreSQL 9.1所使用的CTE和窗口分区的理解。 (示例取自我的另一个问题How to remove duplicate rows。)情况是,cdesc是(从以前的数据库)添加了不必要的字符以保持每个cdesc文本条目不同(和唯一)的文本字段。使用CTE与窗口PARTITION BY和PostgreSQL中的字符串模式匹配的困难

问题是如何组合表CPT中与“切除/活检病理学”的字符串模式相匹配的所有条目。

这样做失败由于“规划”的分组完整的(也是唯一的)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表的定义(从前面的问题)如:

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更新被调用,以在实验室中表记录移动到新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; 
+1

你是什么意思,但我仍然不清楚upd_lab cte被称为是什么?你显然是这样称呼它的,它起作用了...... [从这里阅读手册](http://www.postgresql.org/docs/current/interactive/queries-with.html)。 –

+0

@ErwinBrandstetter如果我理解正确,那么对于父删除访问的每一行,“With”(即计划和upd_lab)都将自动执行(没有父删除中的显式调用)。对? :) –

+1

几乎如此。但是,数据修改CTE的处理方式与简单CTE不同(只有“SELECT”)。详细信息:http://stackoverflow.com/a/15810159/939860 –

回答

1

只需卸下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; 
+0

upd_lab cte如何被调用?谢谢 –