Using MERGE to insert rows when matched? - sql

I'm using MERGE to insert records in a table but only if a column in the source satisfies a condition.
Is the following a valid MERGE statement:
MERGE INTO sometable AS [Target] USING
(
--Here SELECT and INNER JOINS and WHERE
) AS [Source] ON 1 = 0
WHEN NOT MATCHED AND [Source].somecolumn > 0 THEN
INSERT
--columns to insert
VALUES
--their values
EDIT
Modified the statement to show the change according to the docs.

Related

How to Insert records only where records do not exists in table to avoid duplicates Oracle [duplicate]

This question already has answers here:
Oracle Equivalent to MySQL INSERT IGNORE?
(8 answers)
Closed last year.
Hello please see script below i would love to edit the script so it inserts into the table "Book" certain records coming from table "Book2". In other to avoid duplicates , I want it to insert the records into Book only where the records do not exists in the table Book.
Database is Oracle
insert into mol.bkp_Book
select * from mol.bkp_Book2
where session_id in ("3232323","23099999","567890111")
Use a MERGE statement:
MERGE INTO mol.bkp_Book dst
USING (
select *
from mol.bkp_Book2
where session_id in ('3232323','23099999','567890111') -- Single quotes
) src
ON (
dst.session_id = src.session_id
--AND dst.col1 = src.col1 -- Uncomment if you want to compare all columns
--AND dst.col2 = src.col2
--AND dst.col3 = src.col3
)
WHEN NOT MATCHED THEN
INSERT (session_id, col1, col2, col3)
VALUES (src.session_id, src.col1, src.col2, src.col3);

If condition in SQL file vertica

I need to execute insertions for around 10 tables, before inserting I have to check for a condition, condition remains the same for each of the tables, instead of giving that condition within insert query, I wish I could give in if condition (a select query), if satisfied then execute insert statements, is there a way to give if condition in Vertica SQL file ? If condition is not satisfied I dont want to execute any of the insert queries.
If the condition is, for example, that you only insert the data on a Sunday, try this:
a) a test table:
CREATE LOCAL TEMPORARY TABLE input(id,name)
ON COMMIT PRESERVE ROWS AS
SELECT 42,'Arthur Dent'
UNION ALL SELECT 43,'Ford Prefect'
UNION ALL SELECT 44,'Tricia McMillan'
KSAFE 0;
From this table, select with a WHERE condition that tests whether it's sunday -- that's all, see here:
SELECT
*
FROM input
WHERE TRIM(TO_CHAR(CURRENT_DATE,'Day'))='Sunday'
;
id|name
42|Arthur Dent
43|Ford Prefect
44|Tricia McMillan
With a different value for the week day (I'm writing this on a Sunday...), you get this:
SELECT
*
FROM input
WHERE TRIM(TO_CHAR(CURRENT_DATE,'Day'))='Monday'
;
id|name
select succeeded; 0 rows fetched
I use this technique in SQL generating SQL to create a script or an empty file determining on circumstances, and then to call that script (full or empty), implementing a conditional SQL execution that way....
I know it is an old post, but i want to share what i recently solved my problem.
I need to insert in one table or another based on some condition. You first should have a field or value what will be your search condition.
create table tmp1 (
Col1 int null
,Col2 varchar(100) null
)
--Insert values
insert into tmp (Col1,Col2) Values
(1,'Text1')
,(2,'Text2')
--Insert into table001
insert into table001
select
t.field1
,t.field2
,......
from table1 t
inner join tmp t2
on t2.col1 = t.ColX
where 1 = case when t2.Col2 = 'Text1' then 1 else 0 end --Search condition; if 1<>0 then it doesn't do anything; otherwise insert.
--Insert into table002
insert into table002
select
t.field1
,t.field2
,......
from table2 t
inner join tmp t2
on t2.col1 = t.ColX
where 1 = case when t2.Col2 = 'Text2' then 1 else 0 end --Search condition; if 1<>0 then it doesn't do anything; otherwise insert.
Or you can use an UNION/UNION ALL based on this if it is the same working table.
Regards!

Insert multiple in a single query on duplicate insert that duplicate copy to copytable in Postgres

I am inserting multiple records in single query to a table. But, here I am skipping duplicate records. I need to insert those duplicate copies to another table (copytable) with same structure instead of skipping those records. And both the activity needs to be done in a single statement. i.e insert into first table and duplicates records into second table
INSERT INTO manager.vin_manufacturer
(SELECT * FROM( VALUES
('935',' Citroën Brazil','Citroën'),
('ABC', 'Toyota', 'Toyota'),
('ZOM',' OM','OM')
) as tmp (vin_manufacturer_id, manufacturer_desc, make_desc)
WHERE NOT EXISTS (
SELECT 1 FROM manager.vin_manufacturer m where m.vin_manufacturer_id =
tmp.vin_manufacturer_id)
)
You can do that in a single statement, but you have to repeat the where condition that detects the existing rows (just with a negated condition):
with tmp (vin_manufacturer_id, manufacturer_desc, make_desc) as (
VALUES
('935',' Citroën Brazil','Citroën'),
('ABC', 'Toyota', 'Toyota'),
('ZOM',' OM','OM')
), inserted as (
-- insert but skip duplicates
INSERT INTO manager.vin_manufacturer (vin_manufacturer_id, manufacturer_desc, make_desc)
SELECT vin_manufacturer_id, manufacturer_desc, make_desc
FROM tmp
WHERE NOT EXISTS (SELECT 1
FROM manager.vin_manufacturer m
where m.vin_manufacturer_id = tmp.vin_manufacturer_id)
returning * -- return all inserted rows
)
-- insert the duplicates into a different table
insert into duplicates_table (vin_manufacturer_id, manufacturer_desc, make_desc)
select vin_manufacturer_id, manufacturer_desc, make_desc
from tmp
WHERE NOT EXISTS (select *
from inserted i
where i.vin_manufacturer_id = tmp.vin_manufacturer_id)

Bulk insert into SQL Server 2005

Bulk inserting 3 text files each containing 1 lac records into test1 table.
Each of the 3 files has companycode and folio. If compcode and folio already exist in the test1 table, I have to update the table with that particular record from text file else insert it.
But my query is taking lot of time. test1 table has 70 columns
Mmy logic:
import data in dummy table
compare each row of dummy with test1 table
if exists ( select * from #dummy , test1 where condition )
begin
update test1
set col = (#dummy.col)..
inner join #dummy on (condition)
end
else insert
Since the records are in lacs more than 30 min are taken..how can I improve the query?
I assume you're using BULK INSERT to insert data in to temporary table or you could import it using Import Wizard in SQL Server. After that you could use below queries.
Even though you've if(exist) it will update only rows that exists in both the table. So remove if else and write queries directly as shown below:
update test1
set col = (#dummy.col)..
from test1
inner join #dummy on (test1.companycode =#dummy.companycode and test1.folio = #dummy.companycode)
For inserting records that doesn't exits in test1, you could use left join as shown below:
Insert into test1
select column names
from
#dummy left join test1
on test1.companycode =#dummy.companycode and test1.folio = #dummy.companycode
where test1.companycode is null
and test1.folio is null

SQL Server query to Oracle query conversion

I need to write a query in Oracle, but I'm more familiar with SQL Server.
In SQL Server, the query would look as follows: (simplified)
if exists (
select * from table where a=1
)
begin
update table set b=1 where a=1
end else
begin
insert table (a,b) values(1,1)
end
Thanks for any help :)
===============================================================================
This is the Merge option, (I think):
MERGE INTO table T
USING (
SELECT a,b
FROM table
) Q
ON T.a = Q.a
WHEN MATCHED THEN
UPDATE SET T.a = 1
WHEN NOT MATCHED THEN
INSERT table (a,b) VALUES (1,1);
Is this correct?
This should be the correct syntax for Oracle 11g. I'm not an expert on Oracle so maybe someone else could explain it better, but I believe the dual table is used when inserting new values instead or trying too merge is from another table.
MERGE INTO table1 T
USING (
SELECT 1 a, 1 b FROM dual
) Q
ON (T.a = Q.a)
WHEN MATCHED THEN
UPDATE SET b = 1
WHEN NOT MATCHED THEN
INSERT (a,b) VALUES (Q.a,Q.b);
Working example