Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7916185
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T14:42:51+00:00 2026-06-03T14:42:51+00:00

I have two tables of the following form (i.e., every foo is linked to

  • 0

I have two tables of the following form (i.e., every foo is linked to exactly one bar).

CREATE TABLE foo (
    id INTEGER PRIMARY KEY,
    x INTEGER NOT NULL,
    y INTEGER NOT NULL,
    ...,
    bar_id INTEGER UNIQUE NOT NULL,
    FOREIGN key (bar_id) REFERENCES bar(id)
);

CREATE TABLE bar (
    id INTEGER PRIMARY KEY,
    z INTEGER NOT NULL,
    ...
);

It’s easy to copy rows in foo which meet a particular condition using a nested query:

INSERT INTO foo (...) (SELECT ... FROM foo WHERE ...)

But I can’t figure out how to make a copy of the associated row in bar for each row in foo and insert the id of bar into the new foo row. Is there any way of doing this in a single query?

Concrete example of desired result:

-- Before query:

foo(id=1,x=3,y=4,bar_id=100)  .....  bar(id=100,z=7)
foo(id=2,x=9,y=6,bar_id=101)  .....  bar(id=101,z=16)
foo(id=3,x=18,y=0,bar_id=102) .....  bar(id=102,z=21)


-- Query copies all pairs of foo/bar rows for which x>3:

-- Originals
foo(id=1,x=3,y=4,bar_id=101)  .....  bar(id=101,z=7)
foo(id=2,x=9,y=6,bar_id=102)  .....  bar(id=102,z=16)
foo(id=3,x=18,y=0,bar_id=103) .....  bar(id=103,z=21)

-- "Copies" of foo(id=2,...) and foo(id=3,...), with matching copies of
-- bar(id=102,...) and bar(id=103,...)
foo(id=4,x=9,y=6,bar_id=104)  .....  bar(id=104,z=16)
foo(id=5,x=18,y=0,bar_id=105) .....  bar(id=105,z=21)
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T14:42:52+00:00Added an answer on June 3, 2026 at 2:42 pm

    Final version

    … after some more info from OP. Consider this demo:

    -- DROP TABLE foo; DROP TABLE bar;
    
    CREATE TEMP TABLE bar (
      id serial PRIMARY KEY  -- using a serial column!
    , z  integer NOT NULL
    );
    
    CREATE TEMP TABLE foo (
      id     serial PRIMARY KEY  -- using a serial column!
    , x      integer NOT NULL
    , y      integer NOT NULL
    , bar_id integer UNIQUE NOT NULL REFERENCES bar(id)
    );
    

    Insert values – bar first.
    Test data like this would be very helpful in your question:

    INSERT INTO bar (id,z) VALUES
      (100, 7)
    , (101,16)
    , (102,21)
    ;
    
    INSERT INTO foo (id, x, y, bar_id) VALUES
      (1, 3,4,100)
    , (2, 9,6,101)
    , (3,18,0,102)
    ;
    

    Set sequences to current values or we get duplicate key violations:

    SELECT setval('foo_id_seq', 3);
    SELECT setval('bar_id_seq', 102);
    

    Checks:

    -- SELECT nextval('foo_id_seq')
    -- SELECT nextval('bar_id_seq')
    -- SELECT * from bar;
    -- SELECT * from foo;
    

    Query:

    WITH a AS (
        SELECT f.x, f.y, bar_id, b.z
        FROM   foo f
        JOIN   bar b ON b.id = f.bar_id
        WHERE  x > 3
        ),b AS (
        INSERT INTO bar (z)
        SELECT z
        FROM   a
        RETURNING z, id AS bar_id
        )
    INSERT INTO foo (x, y, bar_id)
    SELECT a.x, a.y, b.bar_id
    FROM   a
    JOIN   b USING (z);
    

    This should do what your last update describes.

    The query assumes that z is UNIQUE. If z is not unique, it gets more complex. Refer to Query 2 in this related answer for a ready solution using the window function row_number() in this case.

    Also, consider replacing the 1:1 relation between foo and bar with a single united table.

    Data modifying CTE

    Second answer after more info.

    If you want to add rows to foo and bar in a single query, you can use a data modifying CTE since PostgreSQL 9.1:

    WITH x AS (
        INSERT INTO bar (col1, col2)
        SELECT f.col1, f.col2
        FROM   foo f
        WHERE  f.id BETWEEN 12 AND 23  -- some filter
        RETURNING col1, col2, bar_id   -- assuming bar_id is a serial column
        )
    INSERT INTO foo (col1, col2, bar_id)
    SELECT col1, col2, bar_id
    FROM   x;
    

    I take values from foo, insert them in bar, have them returned together with an auto-generated bar_id and insert that into foo. You can use any other data, too.

    Here is a working demo to play with on sqlfiddle.

    Basics

    Original answer with basic information before clarifications.
    The basic form is:

    INSERT INTO foo (...)
    SELECT ... FROM foo WHERE ...
    

    No parenthesis needed.
    You can do the same with any table

    INSERT INTO foo (...)
    SELECT ... FROM bar WHERE ...
    

    And you can join to the table you insert into in the SELECT:

    INSERT INTO foo (...)
    SELECT f.col1, f.col2, .. , b.bar_id
    FROM   foo f
    JOIN   bar b USING (foo_id);  -- present in foo and bar
    

    It’s just a SELECT like any other – that can include the table you are inserting into. The rows are first read, and then inserted.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have two tables with the following schema: CREATE TABLE sales_data ( sales_time date
I have two tables with the following (simplified) structures: table "Factors" which holds data
I have two database tables with the following structure: actions: action_id int(11) primary key
I have two tables in this project of mine. One table is for the
I am using VB.NET with LINQ to MS SQL. I have two following tables.
I have two tables t1 and t2 as following t1 A B C D
I have two tables that I am joining with the following query... select *
I have two tables as shown in the following diagram : as you saw
I have two tables invoices and pending_payments both of which have the following rows
Suppose I have two tables Main and Other like the following: Main +----------+-----------------------------------+ |

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.