postgresql: INSERT INTO … (SELECT * …)

前端 未结 6 1335
醉话见心
醉话见心 2020-12-04 08:49

I\'m not sure if its standard SQL:

 INSERT INTO tblA 
 (SELECT id, time 
    FROM tblB 
   WHERE time > 1000)  

What I\'m looking for

相关标签:
6条回答
  • 2020-12-04 09:29

    If you want insert into specify column:

    INSERT INTO table (time)
    (SELECT time FROM 
        dblink('dbname=dbtest', 'SELECT time FROM tblB') AS t(time integer) 
        WHERE time > 1000
    );
    
    0 讨论(0)
  • 2020-12-04 09:32

    This notation (first seen here) looks useful too:

    insert into postagem (
      resumopostagem,
      textopostagem,
      dtliberacaopostagem,
      idmediaimgpostagem,
      idcatolico,
      idminisermao,
      idtipopostagem
    ) select
      resumominisermao,
      textominisermao,
      diaminisermao,
      idmediaimgminisermao,
      idcatolico ,
      idminisermao,
      1
    from
      minisermao    
    
    0 讨论(0)
  • 2020-12-04 09:36

    Here's an alternate solution, without using dblink.

    Suppose B represents the source database and A represents the target database: Then,

    1. Copy table from source DB to target DB:

      pg_dump -t <source_table> <source_db> | psql <target_db>
      
    2. Open psql prompt, connect to target_db, and use a simple insert:

      psql
      # \c <target_db>;
      # INSERT INTO <target_table>(id, x, y) SELECT id, x, y FROM <source_table>;
      
    3. At the end, delete the copy of source_table that you created in target_table.

      # DROP TABLE <source_table>;
      
    0 讨论(0)
  • 2020-12-04 09:43
    insert into TABLENAMEA (A,B,C,D) 
    select A::integer,B,C,D from TABLENAMEB
    
    0 讨论(0)
  • 2020-12-04 09:48

    You can use dblink to create a view that is resolved in another database. This database may be on another server.

    0 讨论(0)
  • 2020-12-04 09:54

    As Henrik wrote you can use dblink to connect remote database and fetch result. For example:

    psql dbtest
    CREATE TABLE tblB (id serial, time integer);
    INSERT INTO tblB (time) VALUES (5000), (2000);
    
    psql postgres
    CREATE TABLE tblA (id serial, time integer);
    
    INSERT INTO tblA
        SELECT id, time 
        FROM dblink('dbname=dbtest', 'SELECT id, time FROM tblB')
        AS t(id integer, time integer)
        WHERE time > 1000;
    
    TABLE tblA;
     id | time 
    ----+------
      1 | 5000
      2 | 2000
    (2 rows)
    

    PostgreSQL has record pseudo-type (only for function's argument or result type), which allows you query data from another (unknown) table.

    Edit:

    You can make it as prepared statement if you want and it works as well:

    PREPARE migrate_data (integer) AS
    INSERT INTO tblA
        SELECT id, time
        FROM dblink('dbname=dbtest', 'SELECT id, time FROM tblB')
        AS t(id integer, time integer)
        WHERE time > $1;
    
    EXECUTE migrate_data(1000);
    -- DEALLOCATE migrate_data;
    

    Edit (yeah, another):

    I just saw your revised question (closed as duplicate, or just very similar to this).

    If my understanding is correct (postgres has tbla and dbtest has tblb and you want remote insert with local select, not remote select with local insert as above):

    psql dbtest
    
    SELECT dblink_exec
    (
        'dbname=postgres',
        'INSERT INTO tbla
            SELECT id, time
            FROM dblink
            (
                ''dbname=dbtest'',
                ''SELECT id, time FROM tblb''
            )
            AS t(id integer, time integer)
            WHERE time > 1000;'
    );
    

    I don't like that nested dblink, but AFAIK I can't reference to tblB in dblink_exec body. Use LIMIT to specify top 20 rows, but I think you need to sort them using ORDER BY clause first.

    0 讨论(0)
提交回复
热议问题