Postgres insert with select and values - sql

So I'm trying to insert a value into a secondary table, get the returned id from the insert, and use it together with some values in a prepared statement I'm writing.The return of the first statement(table2) is an id for a foreign key column in the first table.
I want to get the id of table 1 in the end.Something like :
WITH table2ID AS
(
INSERT INTO table2 (value) VALUES ('somevalue') RETURNING id;
)
INSERT INTO table1(table2returnvalue,othervalue) VALUES
(table2ID 'val2') RETURNING id
I can see that I will probably need a transaction as well, because I don't want an isolated in table2 if table1's statement fails for some reason.
Could you please help?

To do this with a CTE its usually easiest to return the entire row (output from table2) and reference that in your second insert query.
WITH table2 AS
(
INSERT INTO table2 ( value )
VALUES ( 'somevalue' )
RETURNING table2.*;
)
INSERT INTO table1 ( table2returnvalue, othervalue )
SELECT table2.id, 'val2'
FROM table2
RETURNING table1.id

I think you're looking for something like this:
WITH table2ID AS
(
INSERT INTO table2 (value) VALUES ('somevalue') RETURNING id;
)
INSERT INTO table1(table2returnvalue,othervalue)
SELECT table2ID.id, 'val2' FROM table2ID;

Related

How to use a WITH query to insert into a table and insert the returning id into another table?

I'm trying to insert a row into a table named table1 if only 'value' exists in table2. The newly created row returns an id and I want to use this id through a WITH query and insert it into a third table named table3.
Here is the sql statement I used.
WITH new_key AS (
INSERT INTO table1(name, value) 
SELECT 'test', value
FROM table2 
WHERE value = 'some_value'
RETURNING id
)
INSERT INTO table3(table1_id)
VALUES (new_key);
The INSERT query in the WITH query works and returns an id. Unfortunately the whole statement returns "new_key column does not exist".
You need to select the value from the CTE:
WITH new_key AS (
INSERT INTO table1(name, value)
SELECT 'test', value
FROM table2
WHERE value = 'some_value'
RETURNING id
)
INSERT INTO table3(table1_id)
SELECT id
FROM new_key;

A sql query to create multiple rows in different tables using inserted id

I need to insert a row into one table and use this row's id to insert two more rows into a different table within one transaction. I've tried this
begin;
insert into table default values returning table.id as C;
insert into table1(table1_id, column1) values (C, 1);
insert into table1(table1_id, column1) values (C, 2);
commit;
But it doesn't work. How can I fix it?
updated
You need a CTE, and you don't need a begin/commit to do it in one transaction:
WITH inserted AS (
INSERT INTO ... RETURNING id
)
INSERT INTO other_table (id)
SELECT id
FROM inserted;
Edit:
To insert two rows into a single table using that id, you could do that two ways:
two separate INSERT statements, one in the CTE and one in the "main" part
a single INSERT which joins on a list of values; a row will be inserted for each of those values.
With these tables as the setup:
CREATE TEMP TABLE t1 (id INTEGER);
CREATE TEMP TABLE t2 (id INTEGER, t TEXT);
Method 1:
WITH inserted1 AS (
INSERT INTO t1
SELECT 9
RETURNING id
), inserted2 AS (
INSERT INTO t2
SELECT id, 'some val'
FROM inserted1
RETURNING id
)
INSERT INTO t2
SELECT id, 'other val'
FROM inserted1
Method 2:
WITH inserted AS (
INSERT INTO t1
SELECT 4
RETURNING id
)
INSERT INTO t2
SELECT id, v
FROM inserted
CROSS JOIN (
VALUES
('val1'),
('val2')
) vals(v)
If you run either, then check t2, you'll see it will contain the expected values.
Please find the below query:
insert into table1(columnName)values('stack2');
insert into table_2 values(SCOPE_IDENTITY(),'val1','val2');

SQL INSERT from select with NULL values

Good afternoon in my timezone.
i have to insert a row in a table but one of the columns are values from another table.So what i want to accomplish is something like this
INSERT TABLE_NAME(COL1,COL2,COL3,COL4) VALUES("VAL1","VAL2","VAL3",(SELECT COL_A FROM TABLE2 WHERE COL_B = 'X'))
But i think the above code is not possible so i use the following code:
INSERT INTO TABLE_NAME(COL1,COL2,COL3,COL4)
SELECT "COL1","COL2","COL3", COL_A FROM TABLE2 T2
WHERE COL_B= "X"
My question is:
I want to insert values even the select does not return values and in this case the COL4 will be NULL
How can i achieve this ?
Thanks in advance
Best regards
No, you cannot insert a row that is not in the table.
If you are expecting one row (in the case of a match), you can use aggregation:
INSERT INTO TABLE_NAME(COL1, COL2, COL3, COL4)
SELECT "COL1","COL2","COL3", MAX(COL_A)
FROM TABLE2 T2
WHERE COL_B = 'X';
This will return NULL if there is no match -- but only one row even if there are multiple matches in the table.
As i understood from your description, only one column is NULL, other 3 columns have values. You should use Select INTO as https://www.w3schools.com/sql/sql_select_into.asp
SELECT COL1,COL2,COL3,COL4 INTO TABLE2 FROM TABLE_NAME WHERE COL_B= "X"
You can create a temp table to store the primary keys of TABLE2 (for eg TABLE2 has primary key 'X', 'Y')
CREATE TABLE #TempPK (COLB int null);
insert into #TempPK(COLB) values ('X');
insert into #TempPK(COLB) values ('Y');
--then you do a FULL OUTER JOIN on your insert select from statement
INSERT INTO TABLE_NAME(COL1, COL2, COL3, COL4)
SELECT "COL1","COL2","COL3", MAX(COL_A)
FROM TABLE2 T2 FULL OUTER JOIN #TempPK TPK
ON T2.COL_B = TPK.COLB
This way you should be able to insert both rows(X and Y) and the Row X should show NULL values all across the row. Hope it makes sense.

select table to select from, dependent on column-value of already given table

for my intention I have to select a table to select columns from dependent on the column-value of an already given table.
First I thought about a CASE construct, if this is possible with sqlite.
SELECT * FROM
CASE IF myTable.column1 = "value1" THEN (SELECT * FROM table1 WHERE ...)
ELSE IF myTable.column1 = "value2" THEN (SELECT * FROM table2 WHERE ...)
END;
I am new to SQL. What construct would be the most concise (not ugly) solution and if I cannot have it in sqlite, what RDBM would be the best fit?
Thanks
Here is a proposal for associating a value from one of two tables for each entry in mytable. I.e. this is making the assumption that mytable does not only contain a single entry for choosing the secondary table.
For details on what this means, see "MCVE" at the end of this answer.
If you want to switch between two secondary tables, based on a single entry in main table, see at the very end of this answer.
Details:
a hardcoded "value1"/"value2" as column1 added on the fly to the result from secondary tables
joining by the faked colummn1 and a secondary join-key, assumption here id
a union all to make a single table from both secondary tables (including the fake column1)
select *
from mytable
left join
(select 'value1' as column1, * from table1
UNION ALL
select 'value2' as column1, * from table2)
using(id, column1);
Output (for the MCVE provided below, "a-f" from table1, "A-Z" from table2):
value1|1|a
value2|2|B
value1|3|c
value1|4|d
value2|5|E
value2|6|F
MCVE:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE mytable (column1 varchar(10), id int);
INSERT INTO mytable VALUES('value1',1);
INSERT INTO mytable VALUES('value2',2);
INSERT INTO mytable VALUES('value1',3);
INSERT INTO mytable VALUES('value1',4);
INSERT INTO mytable VALUES('value2',5);
INSERT INTO mytable VALUES('value2',6);
CREATE TABLE table2 (value varchar(2), id int);
INSERT INTO table2 VALUES('F',6);
INSERT INTO table2 VALUES('E',5);
INSERT INTO table2 VALUES('D',4);
INSERT INTO table2 VALUES('C',3);
INSERT INTO table2 VALUES('B',2);
INSERT INTO table2 VALUES('A',1);
CREATE TABLE table1 (value varchar(2), id int);
INSERT INTO table1 VALUES('a',1);
INSERT INTO table1 VALUES('b',2);
INSERT INTO table1 VALUES('c',3);
INSERT INTO table1 VALUES('d',4);
INSERT INTO table1 VALUES('e',5);
INSERT INTO table1 VALUES('f',6);
COMMIT;
For selecting between two tables based on a single entry in main table (in this case "mytable2":
select * from table1 where (select column1 from mytable2) = 'value1'
union all
select * from table2 where (select column1 from mytable2) = 'value2';
Output (with mytable2 only containing 'value1'):
a|1
b|2
c|3
d|4
e|5
f|6

How to select the record from table and insert into another table?

I wanted to select the last record from the table1 and insert into another table .Here is my query.
Insert into table2 values(select top 1 col1,col2 from table1 order by id desc).
I know for adding the value into table,need to be in cotation.But where to add?
You can select literals to fill in the other columns that table1 can't provide, something like this:
insert into table2 (col_a, col_b, col_c, col_d)
select top 1 col1, col2, 'foo', 'bar'
from table1
order by id desc
Any columns you do not name in the column list will get the default value, or null if no default is defined.
The number and type of columns selected must match the number and type of columns in the insert column list.
In SQL, there are essentially basically two ways to INSERT data into a table: One is to insert it one row at a time, the other is to insert multiple rows at a time. Let's take a look at each of them individually:
INSERT INTO table_name (column1, column2, ...)
VALUES ('value1', 'value2', ...)
The second type of INSERT INTO allows us to insert multiple rows into a table. Unlike the previous example, where we insert a single row by specifying its values for all columns, we now use a SELECT statement to specify the data that we want to insert into the table. If you are thinking whether this means that you are using information from another table, you are correct. The syntax is as follows:
INSERT INTO table1 (column1, column2, ...)
SELECT t2.column3, t2.column4, ...
FROM table2 t2
So, in you case, you can do it like this:
Insert into table2
select top 1 t1.col1,t1.col2 from table1 t1 order by id desc
Or you can use your syntax like this:
declare #col1 type_of_col1, #col2 type_of_col2
select top 1 #col1 = t1.col1, #col2 = t1.col2 from table1 t1 order by id desc
Insert into table2 values(#col1, #col2)
Offcourse, this all works assuming that the column datatypes are matched.