I have two tables with the same columns, There are no unique columns for these tables. Lets say the columns are Col1, Col2, Col3 and Col4. The tables are T1 and T2.
What I want to do is insert all the rows from T2 to T1 where Col1 & Col2 combinations do not exist in T1 already. Col1 is a string and Col2 is an int.
So for example Col1 = "APPLE" and Col2 = "2019". If a row contains Col1 = "APPLE" and Col2=2019 in T2 I do not want to insert it into T1 whereas if a row contains Col1 = "APPLE" and Col2=2020 then I want to insert it into T1.
I am trying to find the easiest solution to do this and cant seem to find a straightforward way using INSERT INTO WHERE NOT EXISTS or using UPSERT.
You can use insert ... select ... where not exists with tuple equality to compare (col1, col2):
insert into t1(col1, col2, col3, col4)
select * from t2
where not exists (
select 1 from t1 where (t1.col1, t1.col2) = (t2.col1, t2.col2)
)
With NOT EXISTS:
insert into t1(Col1, Col2, Col3, Col4)
select Col1, Col2, Col3, Col4
from t2
where not exists (
select 1 from t1
where t1.Col1 = t2.Col1 and t1.Col2 = t2.Col2
)
See a simplified demo.
Related
The goal is to add two values from an existing table, then have the sum value replace the value from the existing table to make the new file my boss wants.
All while keeping the data from the existing table as is...only updating the new one.
After looking around online I started working on an insert statement like the one below:
insert into temptable1 (col1, col2,col3, col4,col5,col6,col7,col8)
select col1, col2, max(col3), max(col4),max(col5),max(col6),max(col7),max(col8)
from temptable2
group by col1, col2
then tried updating the table with the sums:
Update t1
Set t1.col8 = t2.col8
FROM temptable1 t1
INNER JOIN (select col1, col2, sum(col6 + col7) as col8
from temptable2 group by col1, col2) as t2
on t2.col1 = t1.col1
Update t1
Set t1.col5 = t2.col5
FROM temptable1 t1
INNER JOIN (select col1, col2, sum(col3 + col4) as col5
from temptable2 group by col1, col2) as t2
on t2.col1 = t1.col1
Afterwards it goes into another insert statement that talks to the related perma tables in the database. I can execute this without getting any errors but the report I'm getting as a result of this script doesn't look unchanged in the slightest.
temtable2 in this example is the one that would have existing data, temptable1 is the one that should have the summations.
I am having some trouble using a subquery for the IN clause of a query.
Hard-coding the IN .. values allows the query to execute quickly, but using a subquery slows everything down. Is there a way to speed this query up?
SELECT col1, col2, col3 FROM table1
WHERE ...
and col1 in (SELECT col1 FROM table2)
...
*The values for the IN clause will be a list of strings
SELECT col1, col2, col3 FROM table1
WHERE ...
and col1 in ('str1', 'str2', 'str3', ...)
...
The above works fine.
EDIT:
I think I was oversimplifying the problem. The query I am trying to execute looks like this:
SELECT col1, col2, col3, ...
FROM table1 t1, table2 t2
WHERE t1.col1 IN (SELECT col FROM table3)
and t1.col2 < 50
and t2.col3 = t1.col3
...
You cant write select * from . If you give select * from, it doesnot understand which column to compare with from table2. Use the column name you need.
SELECT * FROM table1
WHERE ...
and col1 in (SELECT col1 FROM table2)
...
Use JOIN instead,
and keep an index defined on table1.col1 or table2.col3 or table1.col3 or table3.col :
SELECT col1, col2, col3, ...
FROM table1 t1
INNER JOIN table2 t2 on ( t2.col3 = t1.col3 )
INNER JOIN table3 t3 on ( t1.col1 = t3.col )
WHERE t1.col2 < 50;
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax. You should write the query as:
SELECT col1, col2, col3, ...
FROM table1 t1 JOIN
table2 t2
ON t2.col3 = t1.col3
WHERE t1.col1 IN (SELECT col FROM table3) AND
t1.col2 < 50;
I would write this using EXISTS, rather than IN:
SELECT col1, col2, col3, ...
FROM table1 t1 JOIN
table2 t2
ON t2.col3 = t1.col3
WHERE EXISTS (SELECT 1 FROM table3 t3 WHERE t1.col1 = t3.col) AND
t1.col2 < 50;
The filtering is all on table1; however, the columns are being compared with inequalities. I would try the following indexes: table2(col3), table1(col2, col1), and table3(col).
I have rows in my table that needs deleting based on a few columns being duplicates.
e.g Col1,Col2,Col3,Col4
If Col1,Col2 and Col3 are duplicates regardless of what value is in Col4 I want both these duplicates deleted. How do I do this?
You can do this using the where clause:
delete from t
where (col1, col2, col3) in (select col1, col2, col3
from t
group by col1, col2, col3
having count(*) > 1
);
Group by these IDs and check with HAVING whether there are duplicates. With the duplicates thus found delete the records.
delete from mytable
where (col1,col2,col3) in
(
select col1,col2,col3
from mytable
group by col1,col2,col3
having count(*) > 1
);
Use EXISTS to remove a row if another row with same col1, col2 and col3 exists with a lower col4 value. I.e keep one col1, col2, col3 row.
delete from tablename t1
where exists (select 1 from tablename t2
where t2.col1 = t1.col1
and t2.col2 = t1.col2
and t2.col3 = t1.col3
and t2.col4 < t1.col4)
To remove both/all rows, skip the col4 condition, do a group by instead:
delete from tablename t1
where exists (select 1 from tablename t2
where t2.col1 = t1.col1
and t2.col2 = t1.col2
and t2.col3 = t1.col3
group by t2.col1, t2.col2, t2.col3
having count(*) > 1)
I'm attempting to create a short script which will take all of the fields from Table1 and insert them into Table2. The basic fields (col1, col2, col3, etc.) I have got covered by something like this:
INSERT INTO Table2 (col1, col2, col3, col4, col5, col6, col7)
SELECT col1, col2, col3, col4, col5, SYSDATE, USER
FROM Table1
I am having trouble though inserting the values for 2 fields in particular, col12/col13 of Table2. These columns are standalone in Table1, but in my new Table2 there the value referenced via foreign key ID to Table3/Table4. I'm now attempting to figure out how to do a proper subquery during my table INSERT from Table1 into Table2.
To try and better explain:
// Previously Used for DB
[Table1]
col12 -- CUSTOMER
col13 -- MERCHANT
//---------------
// NEW
[Table2]
col15 -- CUSTOMER_ID
col16 -- MERCHANT_ID
[Table3]
ID
CUSTOMER_DESC
CREATED_DATE
CREATED_BY
[Table4]
ID
MERCHANT_DESC
CREATED_DATE
CREATED_BY
Can anyone provide an example of the proper formatting for such a thing within my INSERT script? I'm envisioning it being something like:
INSERT INTO Table1 (col1, col2, col3, col4)
SELECT col1, col2, col3, [SELECT ID FROM Table3 WHERE Table3.CUSTOMER_DESC == Table2.CUSTOMER])
FROM Table2
My apologies if explanation isn't the clearest.
You need to properly JOIN to Table3, Table4 in order to get the referenced field values:
INSERT INTO Table2 (CUSTOMER_ID, MERCHANT_ID, col1, col2, etc...)
SELECT t3.ID, t4.ID, t1.col1, t2.col2, etc..
FROM Table1 t1
INNER JOIN Table3 t3 ON t1.CUSTOMER = t3.CUSTOMER_DESC
INNER JOIN Table4 t4 ON t1.MERCHANT = t4.MERCHANT_DESC
There should be no problem with the above query provided that there is a 1-1 relationship between Table1 and Table3 on fields CUSTOMER, CUSTOMER_DESC and Table1 and Table4 on fields MERCHANT, MERCHANT_DESC.
SQL Fiddle Demo
You almost got it right.
INSERT INTO Table1 (col1, col2, col3, col12)
SELECT col1, col2, col3, (SELECT customer_desc FROM Table3 WHERE Table3.ID = Table2.col15)
FROM Table2
As I get a lot of answers trying to help me with getting around the error:
I am mostly interested in a way to do error handling and to detect the table row creating an error than getting around my actual problem which I only use to illustrate what is coded in the stored procedure.
I am doing an SQL Insert statement in a stored procedure for entries missing in the table:
INSERT INTO dbo.t1
(col1, col2, col3, col4, col5)
SELECT DISTINCT col1, col2, col3, col4, col5
FROM dbo.t2
WHERE (NOT EXISTS
(SELECT col1, col2, col3, col4, col5
FROM t1 AS Table_1
WHERE (col1 = t2.col1) AND
(col2 = t2.col2) AND
(col3 = t2.col3) AND
(col4 = t2.col4) AND
(col5 = t2.col5))) AND
col2 = 'VALUE'
t1.col1 + t1.col2 and t1.col3 + t1.col4 have a foreign key relation to another table t3.col1 + t3.col2
The stored procedure fails to finish throwing an error message that the foreign key relation has been violated; i.e. there are some entries missing in t3:
Msg 547, Level 16, State 0 [...] INSERT statement is in conflict with
FOREIGN-KEY [..]
What I would like to know is the TABLE ROW of t2 causing the error, optimally the values in this row. I googled quite a lot about SQL error handling, but only found examples providing the coding line raising the error - which is useless information for me...
Any help appreciated
The error is pretty clear, it seams like you are trying to insert a value in the column with the FK constraint that is not found in the primary key column of the referenced table.
From the query you posted, you are trying to insert all values from dbo.t2 that doesn't exist in the first table. Then you can use EXCEPT operator to insert only the values of col1, col2, col3, col4, col5 that found in the dbo.t2 that doesn't present in dbo.t1 something like:
INSERT INTO dbo.t1
(col1, col2, col3, col4, col5)
SELECT * FROM
(
SELECT col1, col2, col3, col4, col5
FROM dbo.t2
EXCEPT
col1, col2, col3, col4, col5
FROM dbo.t1
)
This way you will guarantee that only the rows that doesn't present in dbo.t1 get inserted.
If you want to get the data that cause the duplicate entry you can use the INTERSECT to get them.
INSERT INTO dbo.t1(col1, col2, col3, col4, col5)
SELECT DISTINCT col1, col2, col3, col4, col5
FROM dbo.t2 left join dbo.t1
on t2.col1=t1.col1 and
t2.col2=t1.col2 and
t2.col3=t1.col3 and
t2.col4=t1.col4 and
t2.col5=t1.col5
where t1.col1 is null and t1.col2 is null and t1.col3 is null and t1.col4 is null and t1.col5 is null
I think it is possible, that in t2 you have rows with values which are not exists in t3. (That's why the reference is violated.)
Make sure that t2 has only the values which are exists in t3.
You can try using INNER JOINs on your data to remove violating rows.
Try this using NOT IN
INSERT INTO TABLE_2
(id, name) SELECT t1.id, t1.name
FROM TABLE_1 t1 WHERE t1.id NOT IN (SELECT id FROM TABLE_2)
SELECT column1, column2, column3
FROM Table2 T2
LEFT JOIN Table1 T1 ON T1.col1 = T2.column1 and T1.col2 = T2.column2 and T1.col3=T2.column3
WHERE T1.col1 IS NULL and T1.col2 IS NULL and T1.col3 IS NULL