Home > Software design >  Update using Common Table Expression
Update using Common Table Expression

Time:02-22

I have a pair of tables in a one to many relationship. I want to insert rows in the One table, rows in the Many table, and then update the new row in the One table.

A simplified structure is as below. There is a fiddle at https://dbfiddle.uk/?rdbms=postgres_12&fiddle=8555fb74372b91c8854f7a18e78110c0

Everything works except for the last step, where the new rows is supposed to be updated. I get a NULL for the updated value.

I can’t see what is missing to get this to work. I suspect it has something to do with the correct syntax to update using the FROM clause. According to the documentation, that’s how you can supply additional data to the UPDATE statement. On the other hand, there may be something more fundamental.

I know that I can write a function to do this, and I have already done that. Here I want to get a better understanding of the SQL involved.

CREATE TABLE testsales(
    id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    customerid int,
    total decimal(6,2)
);
CREATE TABLE testitems(
    id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    saleid int REFERENCES testsales(id),
    productid int,
    quantity int,
    price decimal(5,2)
);

with
    customer(id) as (select 562),
    items(productid,quantity) as (values(1489,2),(746,1),(1093,3)),
    newsale as (
        insert into testsales(customerid)
        select id FROM customer
        returning id
    ),
    addsaleitems as(
        insert into testitems(saleid,productid,quantity,price)
        select
            newsale.id, items.productid, items.quantity,100
        from newsale, items
        returning *
    )
update testsales
set total=(select sum(price*quantity) from addsaleitems)
from addsaleitems,newsale
where testsales.id=newsale.id;

In the above sample, the first two CTEs, customer and items are simply there to provide values for what follows. The newsale CTE creates the new row in the One table, addsaleitems adds rows to the Many table, and the rest of it is supposed to update the One table.

CodePudding user response:

As documented, the UPDATE cannot yet see the rows inserted in the same statement.

The trick is to calculate the sum first, right when you insert the row into testsales.

  • Related