使用另一个表的值更新表(PostgreSQL)

时间:2015-04-24 13:58:23

标签: sql postgresql rdbms common-table-expression

我试图用另一个表中的数据更新表(使用PostgreSQL)。我的表是这样的:

+-------------------+-------------------+-----------------------+
|   id_location     |   user_location   |   social_sec_number   |
+-------------------+-------------------+-----------------------+
|   00000000001     |   Jason (null)    |   812.539.037         |
+-------------------+-------------------+-----------------------+
|   00000000002     |   Jennifer (null) |   066.307.382         |
+-------------------+-------------------+-----------------------+
|   00000000003     |   Albert (null)   |   560.732.535         |
+-------------------+-------------------+-----------------------+

我想进入这个:

+-------------------+---------------------------+-----------------------+
|   id_location     |   user_location           |   social_sec_number   |
+-------------------+---------------------------+-----------------------+
|   00000000001     |   Jason (812.539.037)     |   812.539.037         |
+-------------------+---------------------------+-----------------------+
|   00000000002     |   Jennifer (066.307.382)  |   066.307.382         |
+-------------------+---------------------------+-----------------------+
|   00000000003     |   Albert (560.732.535)    |   560.732.535         |
+-------------------+---------------------------+-----------------------+

id_locationuser_location位于同一个表TableLocation中,但social_sec_number位于另一个表中。

我的代码尝试更新它们(此代码不反映表格示例中显示的内容):

WITH tb_cpf
AS (
    SELECT doc.nr_documento_identificacao
    FROM core.tb_usuario_localizacao ul
    INNER JOIN core.tb_localizacao l ON ul.id_localizacao = l.id_localizacao
    INNER JOIN client.tb_pess_doc_identificacao doc ON ul.id_usuario = doc.id_pessoa
    WHERE l.ds_localizacao ilike '%(null)%'
        AND doc.cd_tp_documento_identificacao = 'CPF'
    )
UPDATE core.tb_localizacao AS l
SET l.ds_localizacao = REPLACE(l.ds_localizacao, '(null)', tb_cpf)
WHERE l.id_localizacao IN (
        SELECT l.id_localizacao
        FROM core.tb_usuario_localizacao ul
        INNER JOIN core.tb_localizacao l ON ul.id_localizacao = l.id_localizacao
        INNER JOIN client.tb_pess_doc_identificacao doc ON ul.id_usuario = doc.id_pessoa
        WHERE l.ds_localizacao ilike '%(null)%'
            AND doc.cd_tp_documento_identificacao = 'CPF'
        )
    AND tb_pess_doc_identificacao.id_pessoa = tb_usuario_localizacao.id_usuario
    AND tb_usuario_localizacao.id_localizacao = tb_localizacao.id_localizacao;

我收到了这个丑陋的错误:

ERROR: column "tb_cpf" does not exist
LINE 11: ... of l.ds_localizacao = REPLACE (l.ds_localization, '(null)', tb_cpf) 
                                                                            ^
********** Error **********
ERROR: column "tb_cpf" does not exist
SQL state: 42703
Character: 433

这样,每条记录都可能带有" null"在每张桌子上被社会保障(例如)取代?

2 个答案:

答案 0 :(得分:0)

CTE中的 protected void gvCalloutTeam_SelectedIndexChanged(object sender, EventArgs e) { //////////////////my logic } 与主tb_cpf语句中的任何其他关系一样。您缺少列标识符,因此如果您将UPDATE添加到.nr_documento_identificacao,则更新应该有效:

tb_cpf

答案 1 :(得分:0)

您误解了with条款的使用。可以把它想象成一个视图或像子查询一样。它的工作方式与内存表完全相同。您必须公开您将要使用的所有列。

但是,为什么这么复杂呢?为什么不做这么简单的事情?

update mytable m1

set m1.mycolumn = replace(  m1.mycolumn, 
                            '(null)', 
                            (
                            select mycolumn2 
                            from mytable2 m2 
                            where m2.id = m1.id
                            ) 
                        )

where m1.mycolumn like '%(null)'

或者,如果您真的想使用with(针对性能问题):

with t1 as
(select t.id,
        t.mycolumn
   from mytable
)

update mytable2 t2
   set t2.mycolumn = replace (t2.mycolumn, '(null)', t1.mycolumn)
 where t2.id = t1.id
   and t2.mycolumn like '%(null)'