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

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;

Related

How to Update a SQL table using Union

So I have 2 tables and I want to UPDATE Table 1 so that it is the Union of Table 1 and Table 2. Any suggestions?
It looks like you just want to insert rows of table2 into table1. If so:
insert into table1 (col1, col2)
select col1, col2 from table2
You might be looking to a more subtle logic, like,: insert names that do not exist, and update values on name that exist already. If so, I would recommend on conflict. For this to work, you need a unique constraint on table2(col1), and then:
insert into table1 (col1, col2)
select col1, col2 from table2
on conflict (col1) do update set col2 = excluded.col2

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.

Oracle: Insert into select... in the

What is the advantage of inserting into a select of a table over simply inserting into the table?
eg
insert into
( select COL1
, COL2
from Table1
where 1=2 <= this and above is the focus of the question.
) select COL3, COL4 from Table2 ;
It seems to do the same thing as:
insert into Table1
( COL1, COL2 )
select COL3, COL4 from Table2 ;
This is the first time I've seen this; our Sr Dev says there is some advantage but he can't remember what it is.
It may make sense in a way if one was inserting a "select *..." from a table with lots of columns, and we want to be lazy, but... we're not. We're enumerating each column in the table.
Database is Oracle 11gR2, but this query was written probably in 10g or before.
we want to be lazy
No, we use insert into table(col1, col2) select col2, col2 from ... when there is a lot of records (for example 1M) and we don't want to create a the values section for each. Let's imagine how much time it takes if you write
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 1);
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 2);
...
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 1000000);
insert select is faster way for copying data from one table(several tables) to an another table.
In a nutshell. It's a lot easier. Especially when you have a massive query that you dont wanna rebuild,or if you have a crapton of objects, or values you are inserting.
Without WITH CHECK OPTION specified, I don't know of any purpose for this syntax. If you specify WITH CHECK OPTION, you can effectively implement an ad-hoc check constraint within your insert statement.
insert into
( select COL1
, COL2
from Table1
where 1=2 WITH CHECK OPTION
) select COL3, COL4 from Table2 ;
The above will never insert a record, because 1 will never equal 2.
The statement below will insert a record as long as COL3 is less than 100, otherwise an exception is raised.
insert into
( select COL1
, COL2
from Table1
where COL1 < 100 WITH CHECK OPTION
) select COL3, COL4 from Table2 ;

Copy data into another table

How to copy/append data from one table into another table with same schema in SQL Server?
Edit:
let's say there is a query
select *
into table1
from table2
where 1=1
which creates table1 with the same schema as well as data as in table2.
Is there any short query like this to only copy entire data only into an already existing table?
If both tables are truly the same schema:
INSERT INTO newTable
SELECT * FROM oldTable
Otherwise, you'll have to specify the column names (the column list for newTable is optional if you are specifying a value for all columns and selecting columns in the same order as newTable's schema):
INSERT INTO newTable (col1, col2, col3)
SELECT column1, column2, column3
FROM oldTable
Simple way if new table does not exist and you want to make a copy of old table with everything then following works in SQL Server.
SELECT * INTO NewTable FROM OldTable
This is the proper way to do it:
INSERT INTO destinationTable
SELECT * FROM sourceTable
INSERT INTO table1 (col1, col2, col3)
SELECT column1, column2, column3
FROM table2
Try this:
INSERT INTO MyTable1 (Col1, Col2, Col4)
SELECT Col1, Col2, Col3 FROM MyTable2
Try this:
Insert Into table2
Select * from table1
Insert Selected column with condition
INSERT INTO where_to_insert (col_1,col_2) SELECT col1, col2 FROM from_table WHERE condition;
Copy all data from one table to another with the same column name.
INSERT INTO where_to_insert
SELECT * FROM from_table WHERE condition;
INSERT INTO DestinationTable(SupplierName, Country)
SELECT SupplierName, Country FROM SourceTable;
It is not mandatory column names to be same.
CREATE TABLE `table2` LIKE `table1`;
INSERT INTO `table2` SELECT * FROM `table1`;
the first query will create the structure from table1 to table2 and second query will put the data from table1 to table2
Copy all columns from one table to another table:
INSERT INTO table2
SELECT * FROM table1
WHERE condition;
Copy only some columns from one table into another table:
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;
You can duplicate or "clone" a table's contents by executing:
CREATE TABLE new_table AS SELECT * FROM original_table;
-- for Sql Server users.
if you don't have the new table then you can create the new table with same structure as old table, and also copy data over from old table to the new table. For example:
select * into new_table
from old_table;
also you can copy the column / table structure, and just some of data. For example:
select * into new_table
from old_table
where country = 'DE';

Insert Into Statement - Omitting one Column

I am trying to insert into a table all data but change just the date column
So far I have something like
INSERT INTO MyTable (SELECT * FROM MyTable...)
What I want to do is set one of the columns to be a constant value (like todays date instead of what is selected out)
Does anyone know of an easy way of doing that
INSERT INTO MyTable (col1, col2, col3) (SELECT col1, col2, 'constant' FROM MyTable...)
Yes, you can do it like so:
INSERT INTO MyTable (SELECT MyTable.Id, MyTable.xxx, CONSTANT_VALUE FROM MyTable ...)
I would simply do the ffg
INSERT INTO MyTable
Select col1, col2,....., THE_CONSTANT_VALUE, SOME_OTHER_VALUE from MyTable
You can do this if you specify the columns you are inserting into, something like this:
INSERT INTO MyTable (Col1, Col2, DateVal, StaticValue)
(SELECT Col1, Col2, getdate() As DateVal, 'test' As StaticValue FROM MyTable2)
This would get Col1 and Col2 from MyTable2 but use the getdate() function to get the current date for the DateVal column, and every row inserted would have 'test' for the StaticValue column.
Does this help?
To update all the date field of every row in MyTable to the current date do:
UPDATE MyTable SET thedatecolumn = GETDATE()
If you want to insert from Table1 into Table2 where they have the same structure do:
INSERT INTO Table2 (column1, column2, column3, fixedcolumn) (SELECT column1, column2, 'textvalue' AS staticcolumn, GETDATE() AS functioncolumn FROM Table1)