PostgreSQL: insert from another table - sql

I'm trying to insert data to a table from another table and the tables have only one column in common. The problem is, that the TABLE1 has columns that won't accept null values so I can't leave them empty and I can't get them from the TABLE2.
I have TABLE1:
id, col_1 (not null), col_2(not null), col_3 (not null)
and TABLE2:
id, col_a, col_b, col_c
so how could I insert id from TABLE2 to TABLE1 and fill the col_1-3 with hard coded strings like "data1", "data2", "data3"?
INSERT INTO TABLE1 (id) SELECT id FROM TABLE2 WHERE col_a = "something";
will result in:
ERROR: null value in column "col_1" violates not-null constraint

You can supply literal values in the SELECT:
INSERT INTO TABLE1 (id, col_1, col_2, col_3)
SELECT id, 'data1', 'data2', 'data3'
FROM TABLE2
WHERE col_a = 'something';
A select list can contain any value expression:
But the expressions in the select list do not have to reference any columns in the table expression of the FROM clause; they can be constant arithmetic expressions, for instance.
And a string literal is certainly a value expression.

For referential integtity :
insert into main_tbl (col1, ref1, ref2, createdby)
values ('col1_val',
(select ref1 from ref1_tbl where lookup_val = 'lookup1'),
(select ref2 from ref2_tbl where lookup_val = 'lookup2'),
'init-load'
);

Very late answer, but I think my answer is more straight forward for specific use cases where users want to simply insert (copy) data from table A into table B:
INSERT INTO table_b (col1, col2, col3, col4, col5, col6)
SELECT col1, 'str_val', int_val, col4, col5, col6
FROM table_a

You could use coalesce:
insert into destination select coalesce(field1,'somedata'),... from source;

Related

How do I copy over data from one table to another which has new columns?

I have Table A and Table B.
Both used to have same content but now table A has a few extra non nullable columns. I am trying to copy over data from Table B into Table A but getting an error when I try this query,
INSERT INTO TABLE_A (SELECT * FROM TABLE_B);
This throws the error, ORA-00947: not enough values
INSERT INTO TABLE_A(Col1, Col2, Col3, Col4)
VALUES ((SELECT Col1 FROM TABLE_B), (SELECT Col3 FROM TABLE_B), 'New Column', 'New Column');
This throws the error, ORA-01427: single-row subquery returns more than one row
Try this:
INSERT INTO TABLE_A (Col1, Col2, Col3, Col4)
(SELECT Col1, Col3, 'New Column', 'New Column' FROM TABLE_B);
This should return all the rows from TABLE_B with the correct number of columns.
As you mentioned in question itself table structure of A and B are different.
This is the reason why INSERT INTO SELECT.. is failing.
Below is the query for reference:
INSERT INTO TABLE_A (Col1, Col2, Col3, Col4)
(
SELECT Col1, Col3, 'DUMMY', 'DUMMY'
FROM TABLE_B
);

Insert EXPLICITLY STATED values on some condition from another table in SQL

I spent some time looking but cannot find one answer that satisfies what I am trying to accomplish.
I want to insert some explicitly stated values into table1 based on some condition in table2
The logic goes as follows:
INSERT INTO table1(col1, col2, col3)
VALUES(value1, value2, value3)
ONLY IF (SELECT attribute from table2 WHERE id=1) NOT LIKE 'A')
I NEED to explicitly insert the values and not INSERT SELECT from other table. Really appreciate it.
Edited following clarification from OP.
insert into table1(col1, col2, col3)
select value1, value2, value3
from dual
where (select attribute from table2 where id = 1) != 'A';
This assumes that table1 has exactly one row where id = 1, and the attribute is not null. For a slightly more general case, where there may be no row with id = 1, or there is one such row but the attribute can be null, you can write the where condition like so:
where nvl( (select attribute from table2 where id = 1), 'B' ) != 'A'

PGSQL - How to use output of a select statement in another query?

I realized I didn;t do a good job in asking my question. So giving it a try again.
I am trying to create a pgsql function with below requirement.
I need to store the output of a sql statement in a row/record and use in another statement which selects from third table does some mathematical calculation and insert it second table.
exp:
row = select * from table1;
insert into table2(col21,col22,col23,col24,col25)
values(
select
(col31 - row.col11)/row.col15,
(col32 - row.col12)/row.col14,
(col33 - row.col13)/row.col13,
(col34 - row.col14)/row.col12,
(col35 - row.col15)/row.col11
from table3
);
I would like to know how can I achieve it with pgsql.
Thanks in advance.
No need for anything fancy; normal SQL has you covered:
insert into table2(col1,col2,col3,col4,col5)
select
(b.col31 - a.col11)/a.col15,
(b.col32 - a.col12)/a.col14,
(b.col33 - a.col13)/a.col13,
(b.col34 - a.col14)/a.col12,
(b.col35 - a.col15)/a.col11
from table1 a
cross join table3 b
Should be fairly standard sql.
INSERT INTO TABLE2 (col1, col2, col3, col4, col5)
VALUES (
SELECT * -- Assuming there's only 5 Columns from Table1
FROM TABLE1
)
If you're looking for some sort of temporary table to alter data later and be able to revert back;
CREATE TEMP TABLE temp_table1 AS
SELECT * from table1;
Further note:
If your first column is an automatically incremented pkey and you have data in your 2nd table already - you should just insert values for non-increment columns or you'll have other errors.
INSERT INTO TABLE2 (col2, col3, col4, col5)
VALUES (
SELECT col2, col3, col4, col5 -- Assuming there's only 5 Columns from Table1 and Col1 is a pkey.
FROM TABLE1
)
Basic SQL:
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;
Source: https://www.w3schools.com/sql/sql_insert_into_select.asp
Thank you everyone for your answer. Below is what I came up with.
Ref : https://www.postgresql.org/docs/8.2/static/plpgsql-declarations.html
DECLARE
row table1%rowtype;
BEGIN
select * into strict row from table1;
insert into table2(col21,col22,col23,col24,col25)
values(
select
(col31 - row.col11)/row.col15,
(col32 - row.col12)/row.col14,
(col33 - row.col13)/row.col13,
(col34 - row.col14)/row.col12,
(col35 - row.col15)/row.col11
from table3
);
END;

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.

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.