zoukankan      html  css  js  c++  java
  • postgresql——SQL update fields of one table from fields of another one(列的批量更新)

    https://stackoverflow.com/questions/18797608/update-multiple-rows-in-same-query-using-postgresql

    问题描述:

    I have two tables:

    A [ID, column1, column2, column3]
    B [ID, column1, column2, column3, column4]
    

    A will always be subset of B (meaning all columns of A are also in B).

    I want to update a record with a specific ID in B with their data from A for all columns of A. This ID exists both in A and B.

    Is there an UPDATE syntax or any other way to do that without specifying the column names, just saying "set all columns of A"?

    I'm using PostgreSQL, so a specific non-standard command is also accepted (however, not preferred).

    答:

    The question is old but I felt the best answer hadn't been given, yet.

    Is there an UPDATE syntax ... without specifying the column names?

    General solution with dynamic SQL

    You don't need to know any column names except for some unique column(s) to join on (id in the example). Works reliably for any possible corner case I can think of.

    This is specific to PostgreSQL. I am building dynamic code based on the the information_schema, in particular the table information_schema.columns, which is defined in the ISO SQL standard and most modern RDBMS (except for Oracle) support it. But a DO statement with PL/pgSQL code executing dynamic SQL is totally non-standard PostgreSQL syntax.

    DO
    $do$
    BEGIN
    
    EXECUTE (
    SELECT
    'UPDATE b
     SET   (' || string_agg(quote_ident(column_name), ',') || ')
         = (' || string_agg('a.' || quote_ident(column_name), ',') || ')
     FROM   a
     WHERE  b.id = 123
     AND    a.id = b.id'
    FROM   information_schema.columns
    WHERE  table_name   = 'a'       -- table name, case sensitive
    AND    table_schema = 'public'  -- schema name, case sensitive
    AND    column_name <> 'id'      -- all columns except id
    );
    
    END
    $do$;
    

    Assuming a matching column in b for every column in a, but not the other way round. b can have additional columns.

    WHERE b.id = 123 is optional, to update only a selected row.

    SQL Fiddle.

    Related answers with more explanation:

     

    Partial solutions with plain SQL

    With list of shared columns

    You still need to know the list of column names that both tables share. With a syntax shortcut for updating multiple columns - shorter than what other answers suggested so far in any case.

    UPDATE b
    SET   (  column1,   column2,   column3)
        = (a.column1, a.column2, a.column3)
    FROM   a
    WHERE  b.id = 123    -- optional, to update only selected row
    AND    a.id = b.id;
    

    SQL Fiddle.

    This syntax was introduced with Postgres 8.2 in Dec. 2006, long before the question was asked.
    More details in the manual and this related answer on dba.SE:

    With list of columns in B

    If all columns of A are defined NOT NULL (but not necessarily B),
    and you know the column names of B (but not necessarily A).

    UPDATE b
    SET   (column1, column2, column3, column4)
        = (COALESCE(ab.column1, b.column1)
         , COALESCE(ab.column2, b.column2)
         , COALESCE(ab.column3, b.column3)
         , COALESCE(ab.column4, b.column4)
          )
    FROM (
       SELECT *
       FROM   a
       NATURAL LEFT JOIN  b -- append missing columns
       WHERE  b.id IS NULL  -- only if anything actually changes
       AND    a.id = 123    -- optional, to update only selected row
       ) ab
    WHERE b.id = ab.id;
    

    The NATURAL LEFT JOIN joins a row from b where all columns of the same name hold same values. We don't need an update in this case (nothing changes) and can eliminate those rows early in the process (WHERE b.id IS NULL).
    We still need to find a matching row, so b.id = ab.id in the outer query.

    db<>fiddle here
    Old sqlfiddle.

    This is standard SQL except for the FROM clause.
    It works no matter which of the columns are actually present in A, but the query cannot distinguish between actual NULL values and missing columns in A, so it is only reliable if all columns in A are defined NOT NULL.

    There are multiple possible variations, depending on what you know about both tables.

     

     

     

  • 相关阅读:
    CSS3 页面跳转的动画效果
    JS/React 判断对象是否为空对象
    React 根据官方总结的规范
    ckeditor字数限制
    swfobject.js IE兼容问题
    Jcrop 做图片剪裁 在IE中无法显示问题解决办法
    WebApp 中用 hashchange 做路由解析
    全国省市区Json文件 ,做省市区联动很轻松
    解决用友U8删除用户时提示“用户已启用”不能删除的问题
    CFUpdate高速模式下出现Error #2038提示的解决方案
  • 原文地址:https://www.cnblogs.com/panpanwelcome/p/13050784.html
Copyright © 2011-2022 走看看