delete data from Table1 that doesn't exist in Table2 - oracle

I have 2 different tables and I want to delete records from table1 which does not exist in Tables2
Table1:
select col1 from Table1
Table2:
select
concat('A_',col1)
from
Table2
where
Col2 = '748'
and Col3 = 'D'
and Col4 = 'Account'
now I want to delete the difference from Table1...

This can be done using the minus operation, and an insert into statement.
insert into table3(col) (
select col1 from Table1
minus
select
concat('A_',col1)
from
Table2
where
Col2 = '748'
and Col3 = 'D'
and Col4 = 'Account'
)
Records can then be deleted from table1 using a delete statement like
delete from table1
where col1 in (
select col1 from Table1
minus
select
concat('A_',col1)
from
Table2
where
Col2 = '748'
and Col3 = 'D'
and Col4 = 'Account'
)

delete from table1 t1
where not exists ( select * from table2 where col2 || col3 || col4 = t1.col1 );
This will work EXCEPT for the following situation; you need to explain what you want in that case. The DELETE statement can be modified to accommodate.
If t1.col1 is NULL, it will be deleted even if there are rows in table2 where col2, col3 and col4 are all NULL. Is that situation possible (where t1.col1 and col2, col3, col4 in table2 are all NULL? In that case, should the row in t1 be kept rather than deleted?

Related

Error when inserting CTE table values into physical table

I have a complex query that creates a master CTE_Table form other CTE_Tables. I want to insert the results of the master CTE_Table into a physical table. I'm using Teradata version 15.10.04.03
SELECT Failed. [3707] Syntax error, expected something like a 'SELECT' keyword or '(' or a 'TRANSACTIONTIME' keyword or a 'VALIDTIME' keyword between ')' and the 'INSERT' keyword.
DROP TABLE dbname.physicalTablename ;
CREATE MULTISET TABLE dbname.physicalTablename ,
NO FALLBACK ,
NO BEFORE JOURNAL,
NO AFTER JOURNAL,
CHECKSUM = DEFAULT,
DEFAULT MERGEBLOCKRATIO
(
col1 INTEGER,
col2 INTEGER,
col3 INTEGER
)
NO PRIMARY INDEX ;
WITH
cteTable3 AS
( SELECT A.colA, A.colB, A.colC, B.col1, B.col2, B.col3
FROM cteTable1 A INNER JOIN cteTable2 ON (blah blah blah) ),
cteTable2 AS
( SELECT col1, col2, col3 FROM SourceTableB ),
cteTable1 AS
( SELECT colA, colB, colC FROM SourceTableA )
INSERT INTO dbname.physicalTablename
( col1, col2, col3, col4, col5, col6 )
SELECT
(C3.colA, C3.colB, C3.colC, C3.col1, C3.col2, C3.col3)
FROM cteTable3 C3 ;
While you are missing the INSERT portion of the question, I think the following might clear things up. The correct format for using a CTE in an INSERT is:
INSERT INTO <tablename>
WITH <cte> AS (SELECT...)
SELECT <fields> FROM <cte>
Consider the following:
CREATE MULTISET VOLATILE TABLE tmp AS (SELECT 'bobby' as firstname) WITH DATA ON COMMIT PRESERVE ROWS;
INSERT INTO tmp
WITH cte AS (select 'carol' as firstname)
SELECT * FROM cte;
SELECT * FROM tmp;
DROP TABLE tmp;

joining based on columns priority

I want to join 2 tables based on columns priority
ex. Suppose Table1 has six columns(Col1,Col2,Col3,Col4,Col5,Col6)
If i want to join Table 1 with table2 (Col1,Col2,Col3,Col4,Col5,Col7), it should
otherwise
Select Table2.col7
where
first check col1 , col2 and col3 if match found no need go check more
second check col1 , col2 if match found no need go check more
third check col1 if match found no need go check more
last ignore all col1 , col2 and col3
AND Table1.Col4=Table2.Col4
AND Table1.Col5=Table2.Col5
I may not be clear with my words, if any concern please shout
You cannot tell SQL to try to join on a certain condition first and in case it finds no match to go on searching. What you can do is join all allowed combinations (matches on col4 and col5 in your case) and then rank your matches (such that a match on col1 and col2 and col3 is considered best etc.). Then only keep the best matches:
select col7
from
(
select
t1.*,
t2.*,
row_number() over
(
partition by t1.col4, t1.col5
order by case
when t2.col1 = t1.col1 and t2.col2 = t1.col2 and t2.col3 = t1.col3 then 1
when t2.col1 = t1.col1 and t2.col2 = t1.col2 then 2
when t2.col1 = t1.col1 then 3
else 4
) as rn
from table1 t1
join table2 t2 on t2.col4 = t1.col4 and t2.col5 = t1.col5
)
where rn = 1;
Select t2.col7
from Table1 t1 inner join Table2 t2
on
case
when t1.col1 = t2.col1 then 1
when t1.col2 = t2.col2 then 1
when t1.col3 = t2.col3 then 1
when t1.Col4=t2.Col4
and t1.Col5=t2.Col5 then 1
else 0 end = 1
;

Generate difference between 2 tables listing columns from both tables

Have 2 tables with same columns and want to generate the difference between the tables and want to show the difference listing all columns from both tables
example:
select a.*,b.* from (
(
select a.col1,a.col2 from
(select col1, col2 from table1 minus select col1, col2 from table2) as a
)
union
(
select b.col1, b.col2 from
(select col1, col2 from table2 minus select col1, col2 from table2) as b
)
)
The result should be
a.col1 a.col2 b.col1 b.col2
a.FName a.ZipCode b.FName b.ZipCode
John <same value> Jane <same value as A>
Alpha 1234 Beta 2345
My query returns exception that it is missing R parenthesis after the 1st minus keyword
I think you are trying to find rows from table a which are missing in table b and rows in table b which are missing from table a. However, there is no point in joining these two sets. Try the following query and see if it works for you.
SELECT col1, col2, 'Missing from table 2' title
FROM
(
SELECT col1,
col2
FROM table1
MINUS
SELECT col1,
col2
FROM table2
)
UNION ALL
SELECT col1, col2, 'Missing from table 1' title
FROM
(
SELECT col1,
col2
FROM table2
MINUS
SELECT col1,
col2
FROM table1
)

SQL Server 2012: Update table with inner join after sorted

I am using SQL Server 2012. I have a table called table1 like below:
Id col1 col2 col3 Name
1 a b abc null
2 b c mno null
And I have another table table2, like below:
Id col1 col2 col3 Name
1 % % abc Name1
2 a % abc Name2
3 % b abc Name3
4 a b abc Name4
I have to update Name column in Table1 From Name column in Table2 based on columns: col1, col2 and col3.
The Id = 1 in the table1 finds all 4 matches in the table because I am using like operator in col1 and col2 to compare(why I am using like is if it didn't find exact match it should accept % as a match).
Now my problem is if exact match is there for the columns col1, col2 and col3 in the table, it should consider that only not the rows with '%' value. For example, for the Id=1 in the table1, the result should be from id=4 in the table2.
I tried with following query:
UPDATE table1
SET name = t2.Name
FROM (SELECT TOP 1
t1.id, t2.name
FROM table1 t1
INNER JOIN table2 t2
ON t1.col3 = t2.col3 AND t1.col1 LIKE t2.col1
AND t1.col2 LIKE t2.col2
ORDER BY t2.col1, t2.col2) AS t3
WHERE id = t3.id;
But I am not getting result which I expected. And also, there are 8,000,000 records are there in table1 so it should not affect performance.
Please help to fix this issue.
At a first try, I suggest this:
UPDATE table1
SET name = t2.Name
FROM (SELECT TOP(1) *
FROM (SELECT
t1.id, t2.name, t2.col1, t2.col2, 2 As ord
FROM table1 t1
INNER JOIN table2 t2
ON t1.col3 = t2.col3 AND t1.col1 LIKE t2.col1
AND t1.col2 LIKE t2.col2
UNION ALL
SELECT
t1.id, t2.name, t2.col1, t2.col2, 1 As ord
FROM table1 t1
INNER JOIN table2 t2
ON t1.col3 = t2.col3 AND t1.col1 = t2.col1
AND t1.col2 = t2.col2
) DT
ORDER BY ord, col1, col2) AS t3
WHERE id = t3.id;

Insert data into multiple table from one table using a procedure [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have one parent table which consists of around 150 columns. I need to get the records from the parent table and insert them into 11 different child tables, which have the column names and data types.
Oracle has a very convenient INSERT ALL command that can help in this case.
The syntax of unconditional version is:
INSERT ALL
INTO child1( col1, col2, col3 ) VALUES( col1, col2, col3 )
INTO child2 VALUES( col1, col2, col3 )
INTO child3 ( col1, col2, col3 )
INTO child4
SELECT col1, col2, col3
FROM parent
-- WHERE some conditions;
A link to a demo: --> http://sqlfiddle.com/#!4/3eb62/1
The above command retrieves all rows from the parent table using SELECT ... FROM ... (at the bottom), then, for each retrieved record, it executes all INSERT ... statements.
If the SELECT clause has also a WHERE conditions clause, then only rows that meet these conditions will be inserted.
The INSERT part of the query in the example could have various forms:
A full form with explicitely definied columns of source and destination tables:
INTO dest_table( destcol1, ... destcolN ) VALUES (sourcecol1, ..., sourcecolN)
A shortened form where only columns from source table are given
INTO dest_table VALUES (sourcecol1, ..., sourcecolN)
Another shortened form where only columns from destination table are given
INTO dest_table( destcol1, ... destcolN )
or the simplest:
INTO dest_table
INSERT ALL has also a conditional version:
INSERT ALL
WHEN 1=1 THEN INTO child1( col1, col2, col3 ) VALUES( col1, col2, col3 )
WHEN col1 <> 2 THEN INTO child2 VALUES( col1, col2, col3 )
WHEN col3 < 3 THEN INTO child3 ( col1, col2, col3 )
WHEN col2 = 'rec 3' THEN INTO child4
SELECT col1, col2, col3
FROM parent;
A link to a demo: ---> http://sqlfiddle.com/#!4/e7da3/1
This version inserts rows only when a condition specified after WHEN clause is meet.For each selected rows always all conditions are evaluated.
There is also another conditional form: INSERT FIRST
INSERT FIRST
WHEN col1 >= 4 THEN INTO child1( col1, col2, col3 ) VALUES( col1, col2, col3 )
WHEN col1 >= 3 THEN INTO child2 VALUES( col1, col2, col3 )
WHEN col1 >= 2 THEN INTO child3 ( col1, col2, col3 )
WHEN col1 >= 1 THEN INTO child4
SELECT col1, col2, col3
FROM parent;
A link to a demo: http://sqlfiddle.com/#!4/a421e/1
Here, for each source row, Oracle evaluates conditions from top to bottom, and when some condition is true, then executes only this one INSERT statement, and skips remaining inserts.
------- EDIT -------
An example how to do it in a procedural way:
CREATE OR REPLACE PROCEDURE name
AS
BEGIN
INSERT ALL
INTO child1( col1, col2, col3 ) VALUES( col1, col2, col3 )
INTO child2 VALUES( col1, col2, col3 )
INTO child3 ( col1, col2, col3 )
INTO child4
SELECT col1, col2, col3
FROM parent ;
-- if commit is required, place it here
-- COMMIT;
END;
/

Resources