Issue Insert Into (BigTable1) SELECT From (BiggerTable2) - select

I am selecting a set of data from a bigTable1 (index-ed) and then inserting them into another bigTable2 (index-ed)
I have two options: Which is a good idea:
Option: 1
INSERT INTO bigTable2 (bigTable2.Col1, bigTable2.Col2)
SELECT bigTable1.Col1, bigTable1.Col2 FROM bigTable1 (nolock)
WHERE bigTable1.col3 between #value1 and #value2
Option: 2
CREATE #TEMP (Col1 int, Col2 varchar(200))
INSERT INTO #TEMP (Col1, Col2)
SELECT bigTable1.Col1, bigTable1.Col2 FROM bigTable1 (nolock)
WHERE bigTable1.col3 between #value1 and #value2
INSERT INTO bigTable2 (bigTable2.Col1, bigTable2.Col2)
SELECT Col1, Col2 FROM #TEMP
I do not want to lock the bigTable1. Please advise which one is the better one between the two? Is there any other suggestion?

If you don't want to lock the table, then go with the first approach. It's a one-step procedure and, no matter how long it takes, you keep the table unlocked, so you don't block others.
The second option would be appropriate in case you wanted the table locked during the select. Having to fill an empty, non-indexed table would be faster, thus keeping your table locked for a shorter period.

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;

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.

PostgreSQL - INSERT INTO statement

What I'm trying to do is select various rows from a certain table and insert them right back into the same table. My problem is that I keep running into the whole "duplicate PK" error - is there a way to skip the PK field when executing an INSERT INTO statement in PostgreSQL?
For example:
INSERT INTO reviews SELECT * FROM reviews WHERE rev_id=14;
the rev_id in the preceding SQL is the PK key, which I somehow need to skip. (To clarify: I am using * in the SELECT statement because the number of table columns can increase dynamically).
So finally, is there any way to skip the PK field?
Thanks in advance.
You can insert only the values you want so your PK will get auto-incremented
insert into reviews (col1, col2, col3) select col1, col2, col3 from reviews where rev_id=14
Please do not retrieve/insert the id-column
insert into reviews (col0, col1, ...) select col0, col1, ... from reviews where rev_id=14;

select data from 8 tabels into one temp table

I need to insert data from several tables with all the same field names into one temp table, i know i can use cursor/loop to do this, i wanted to know is there a quicker way of doing this.
select from table 1, table 2, table 3, into #temptable.
select * into #temptable from table1
insert into #temptable select * from table2
insert into #temptable select * from table3
The first query creates the temp table on insert, the rest just keep adding data.