How can I do something like this in PostgresQL? - postgresql

Here is the snippet that I would like to happen. Is this possible?
INSERT INTO join_table_1(table_1_id,table_2_id)
SELECT id, (INSERT INTO table_2(id) VALUES (uuid_generate_v4()) RETURNING id)
FROM table_1
Looking at TRIGGER also but I can't find a way to return the id of the newly inserted row

It's not exactly clear to me what you are trying to achieve, but I think you are looking for a data modifying CTE
with new_t2 as (
INSERT INTO table_2(id)
VALUES (uuid_generate_v4())
RETURNING id
)
INSERT INTO join_table_1 (table_1_id, table_2_id)
SELECT id, (select id from new_t2)
FROM table_1

Related

Liquibase insert select multiple rows postgres

I want to insert into table1 multiple rows from table2. The problem is that I have some fields in table1 that I want to compute, and some rows that I want to select from table2. For example something like this:
insert into table1 (id, selectField1, selectField2, constant)
values ((gen_random_uuid()), (select superField1 from table2), (select superField2 from table2), 'test');
So the logic is to select superField1 and superField2 from all the rows in the table2 and insert them into table1 with constant value test and generated uids. superField1 and superField2 should be from the same row in table2 when inserting in table1. How can I achieve something like this using liquibase?
P.S: I'm using <sql> tag since it's easier to implement using SQL than using XML changeset, but if you know how to do it in XML that would be appreciated too, but just in SQL will be enough too. DBMS is postgres.
Don't use the VALUES clause if the source is a SELECT statement:
insert into table1 (id, selectField1, selectField2, constant)
select gen_random_uuid(), superField1, superField2, 'test'
from table2;

How to use the same common table expression in two consecutive psql statements?

I'm trying to perform a pretty basic operation with a few steps:
SELECT data from table1
Use id column from my selected table to remove data from table2
Insert the selected table from step 1 into table2
I would imagine that this would work
begin;
with temp as (
select id
from table1
)
delete from table2
where id in (select id from temp);
insert into table2 (id)
select id from temp;
commit;
But I'm getting an error saying that temp is not defined during my insert step?
Only other post I found about this is this one but it didn't really answer my question.
Thoughts?
From Postgres documentation:
WITH provides a way to write auxiliary statements for use in a larger
query. These statements, which are often referred to as Common Table
Expressions or CTEs, can be thought of as defining temporary tables
that exist just for one query.
If you need a temp table for more than one query you can do instead:
begin;
create temp table temp_table as (
select id
from table1
);
delete from table2
where id in (select id from temp_table);
insert into table2 (id)
select id from temp_table;
commit;

Insert records from one table to another and then delete inserted records

I am using this query to insert record from one table into another table:
insert into watched_url_queue_work select * from watched_url_queue
on conflict do nothing
The unique constraints on the target table mean not all are inserted.
What I want to now do is delete all of the records that I just inserted but I am not sure of syntax.
I want something like (query not working just my guess at it):
delete from watched_url_queue q
where q.target_domain_record_id in
(
insert into watched_url_queue_work select * from watched_url_queue
on conflict do nothing
returning watched_url_queue_work.target_domain_record_id
)
You can do this with a CTE:
with inserted as (
insert into watched_url_queue_work
select * from watched_url_queue
on conflict do nothing
returning watched_url_queue_work.target_domain_record_id
)
delete from watched_url_queue q
using inserted
where q.target_domain_record_id = inserted.target_domain_record_id;
(The q.target_domain_record_id in (select … from inserted) approach works as well.)

TSQL - CTE/#Temp Table

In SSMS 2016 I have created a CTE and then immediately after the statement, I delete some rows from the CTE.
WITH cte AS
(
SELECT [GroupID], [UserID]+0.5, [Value] from dbo.myTable
)
DELETE FROM cte WHERE concat(GroupID, UserID) in (select concat(GroupID, UserID) as Concat from cte group by GroupID)
However, I want to then INSERT the remaining rows into the existing table, but when I try, I get the following error: "Invalid object name 'cte'."
I suspect the issue has something to do with the way CTEs work. As I am fairly new to them, I'm not sure, but it seems like a CTE can only be referenced once immediately following the WITH AS? Is that true? Is there a way around this? How can I insert data from the CTE?
I was thinking about using a temp table somehow, but I don't know if there's really a difference.
cte's are one and done. You run one query with them and then they go away. You can use a temp table instead and that will persist for the duration of your session.
SELECT [GroupID], [UserID], [Value]
INTO #temp
from dbo.myTable
DELETE FROM #temp
WHERE concat(GroupID, UserID) in (select concat(GroupID, UserID) as Concat from #temp group by GroupID)
INSERT INTO your_table (col1, col2)
SELECT col1, col2
FROM #temp
DROP TABLE #temp
As for the high level diff's between cte's and temp tables. Temp tables are physical storage and you can index them. CTE's are named subqueries and not stored as tabled/objects.

how to use results from first query in second query

Ive been reading about mysqli multi_query and couldnt find a way to do this (if its possible)
$db->multi_query("SELECT id FROM table WHERE session='1';
UPDATE table SET last_login=NOW() WHERE id=table.id");
It doesnt seem to work. I am trying to use the id of the first query to update the second. is this possible
UPDATE table
SET last_login = NOW()
WHERE id IN (SELECT id
FROM table2
WHERE session = '1')
That will update all your records with session = '1'. Assuming of course that the subquery returns more than one result set, which from what I can see, it will.
This also allows you to drop the multi_query() method, as it's just a single query.
In response to the comment:
According to http://lists.mysql.com/mysql/219882 this doesn't appear to be possible with MySQL. Although I suppose you could go for something like:
$db->multiquery(
"UPDATE table
SET last_login = NOW()
WHERE id IN (SELECT id
FROM table2
WHERE session = '1');
SELECT id
FROM table2
WHERE session = '1';"
);
Which is ugly, performing the same query twice, but should do what you want.