Oracle: Insert into select... in the - sql

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 ;

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

How Can I Use the Max Function to Filter a List and Insert Into

Is there a way to do something like:
Insert Into (col1, col2, col3)
Select col1, col2, col3, max(col4)
From mytable
Group By col1, col2, col3
That gives me: The select list for the INSERT statement contains more items than the insert list.
I want to use the max function to filter out dupes but when I select this extra field, the order of fields and number of fields doesn’t match up. How can I filter a list from a table, use the max function, and insert all records except the ones in the max field?
I want to use the max function to filter out dupes
Well, I suspect that you actually want distinct:
insert into my_target_table(col1, col2, col3)
select distinct col1, col2, col3 from my_source_table
This will insert one record in the target table for each distinct (col1, col2, col3) tuple in the source table.
You are describing something like this:
Insert Into (col1, col2, col3)
select col1, col2, col3
from mytable
where t.col4 = (select max(t2.col4)
from mytable t2
where t2.col1 = t.col1 and t2.col2 = t.col2 and t2.col3 = t.col3
);
However, this is pretty much equivalent to select distinct (NULL values might be treated differently). You probably want dupes defined on only one column, so I'm thinking:
insert into (col1, col2, col3)
select col1, col2, col3
from mytable
where t.col4 = (select max(t2.col4)
from mytable t2
where t2.col1 = t.col1
);

Insert a row into the table if it does not exist using SQL

I want to insert a row into the table if it does not exist.
I want to check if the col1 , col2 combination exists in the table.If not I have to insert the data.I have written a query like below , but it is not working.Can some one please help me.
INSERT INTO TABLE1 (COL1 , COL2 , COL3, COL4)
VALUES ( 1234 , 4567 , 'test_name_int' , 'test_disp_name' )
WHERE NOT EXISTS ( SELECT * FROM TABLE1 WHERE COL1 = 1234 and COL2 = '4567');
MERGE INTO is another good option. You could perform update too, if required.
This checks whether col1,col2 of the source and destination match. If they do not,then it does insert. you could also use WHEN MATCHED THEN UPDATE when required to do so.
MERGE INTO TABLE1 d
USING (SELECT 1235 COL1,
4568 COL2,
'test_name_int' COL3,
'test_disp_name' COL4
FROM DUAL) s
ON (d.COL1 = s.col1 AND d.COL2 = s.COL2)
WHEN NOT MATCHED
THEN
INSERT (COL1,
COl2,
COl3,
COl4)
VALUES (s.COl1,
s.COL2,
s.COL3,
s.COL4);
Maybe something like that:
Insert Into TABLE1
Select 1234 , 4567 , 'test_name_int' , 'test_disp_name'
From Dual
WHERE NOT EXISTS ( SELECT * FROM TABLE1 WHERE COL1 = 1234 and COL2 ='4567')

sql insert into table from select without duplicates (need more then a DISTINCT)

I am selecting multiple rows and inserting them into another table. I want to make sure that it doesn't already exists in the table I am inserting multiple rows into.
DISTINCT works when there are duplicate rows in the select, but not when comparing it to the data already in the table your inserting into.
If I Selected one row at a time I could do a IF EXIST but since its multiple rows (sometimes 10+) it doesn't seem like I can do that.
INSERT INTO target_table (col1, col2, col3)
SELECT DISTINCT st.col1, st.col2, st.col3
FROM source_table st
WHERE NOT EXISTS (SELECT 1
FROM target_table t2
WHERE t2.col1 = st.col1
AND t2.col2 = st.col2
AND t2.col3 = st.col3)
If the distinct should only be on certain columns (e.g. col1, col2) but you need to insert all column, you will probably need some derived table (ANSI SQL):
INSERT INTO target_table (col1, col2, col3)
SELECT st.col1, st.col2, st.col3
FROM (
SELECT col1,
col2,
col3,
row_number() over (partition by col1, col2 order by col1, col2) as rn
FROM source_table
) st
WHERE st.rn = 1
AND NOT EXISTS (SELECT 1
FROM target_table t2
WHERE t2.col1 = st.col1
AND t2.col2 = st.col2)
If you already have a unique index on whatever fields need to be unique in the destination table, you can just use INSERT IGNORE (here's the official documentation - the relevant bit is toward the end), and have MySQL throw away the duplicates for you.
Hope this helps!
So you're looking to retrieve all unique rows from source table which do not already exist in target table?
SELECT DISTINCT(*) FROM source
WHERE primaryKey NOT IN (SELECT primaryKey FROM target)
That's assuming you have a primary key which you can base the uniqueness on... otherwise, you'll have to check each column for uniqueness.
pseudo code for what might work
insert into <target_table> select col1 etc
from <source_table>
where <target_table>.keycol not in
(select source_table.keycol from source_table)
There are a few MSDN articles out there about this, but by far this one is the best:
http://msdn.microsoft.com/en-us/library/ms162773.aspx
They made it real easy to implement and my problem is now fixed. Also the GUI is ugly, but you actually can set minute intervals without using the command line in windows 2003.

join two tables into one big table

I have two tables with the same columns, and I need to copy one table's rows to the other table's rows to create one big table with all the values from both tables. Right now I am doing this query to return the same thing:
SELECT col1, col2, col3 from Table1
union
SELECT col1, col2, col3 from Table2
However, it seems horribly inefficient, and on my system is very slow (returns 1210189 records).
May it work to just do:
SELECT col1, col2, col3
INTO Table1
FROM Table2
Start with union all:
select col1, col2, col3 from Table1
union all
select col1, col2, col3 from Table2
Your query is trying to deduplicate things, which would slow it down considerably.
I think the best option is to create a view in sql server, this will optimize the performance of the query:
SELECT col1, col2, col3 from Table1
union all
SELECT col1, col2, col3 from Table2
(As other users said: "union" is used to select distinct values from two tables
where as "union all" is used to select all values including
duplicates from the tables.)
At the same time I would restrict the number of rows I get from the database if i am writing them for a web and if this is giving me problems, with the new functions of Sql Server 2005 row_number(), with this I would page results.
You could use this to fill the second table:
Insert into table2 select * from table1;
Or if you want to be more specific:
Insert into table2(col1, col2, col3) select col1, col2, col3 from table1;
(Note: some DBMSs might require putting parenthesis around the SELECT clause.)
select * into new table(your new table name)
from table1.col1,table1.col2,table2.col1;
here columns can be your required columns .
select * into newtable from table1
union all
select * from table2
Worked well. Guidelines, both tables have exact same column names :)