why this two select statement doesnt' give same answer - oracle

i'm using oracle 11g. i want to know why these two query giving different answer?
logically they are same:
select * from tableA where
exists (select * from tableB where tableA.ID != tableB.ID);
select * from tableA where
not exists (select * from tableB where tableA.ID = tableB.ID);
in the first one i'm selecting every thing that not exist.
in the second one i'm not selecting everything that exist.
note ("exist" changed to "not exist) and ("!=" changed to "=")
look same right? but they give totally different answer

This statement is probably going to return all values in A:
select *
from tableA
where exists (select * from tableB where tableA.ID != tableB.ID);
The only time a row will fail to match is when it is the same as all rows in TableB that have a non-NULL values in ID. So, if TableB has at least two rows with different ids, then all rows in tableA will be returned.
This statement:
select *
from tableA
where not exists (select * from tableB where tableA.ID = tableB.ID);
Is saying that there is no id in TableB that matched the id in TableA. This would be what you want 99% of the time.

The first statement returns A values different from any B value.
The second statement returns A values different from all B values.

Related

Oracle MINUS operator and delete

You can insert records into table B if they are in table A
insert into B
select * from A
minus
select * from B
How do you delete records that are in B and not in A?
select * from B
minus
select * from A
How to delete records?
The assumption is that we do not have a primary key or a unique one.
You can do it like this:
delete from a2
where (COLUMN1, COLUMN2, COLUMN3, ...) in (select * from a2
minus
select * from a1);
It works, but you have to enter the column names in the where clause. Can not do delete in such a beautiful way as insert into select * from ...?
If you wanted to continue with your current approach, you should not use select * in your minus query. Rather, you should always explicitly list out the columns which you want to use.
But, I would use an EXISTS query here:
DELETE
FROM tableB b
WHERE NOT EXISTS (SELECT 1 FROM tableA a
WHERE a.col1 = b.col1 AND
a.col2 = b.col2 AND
a.col3 = b.col3 AND ...);
Best practice going forward would to have a primary key column in the A table. Then, you would only need to check that column against the B table for uniqueness.

twice insert into the same table

select * into tableA from dataA.
I have created a table tableA.
Next time,
insert * into tableA from dataB. it doesn't work. Because tableA is already exist.
I need insert data twice instead of unioning dataA and dataB.
select * into tableA from dataA.
Next,
INSERT INTO tableA(colum1,colum2)<--Not *
SELECT (colum1,colum2)
FROM B

update a column with another table column in sql with the same column being the id

I am trying to update columnA in tableA. The new values of ColumnA is extracted from tableB ColumnB, using column a as the ID. I am using the following queries, but i am unable to update the table.
update tableA a set columnA = (select b.columnB from tableb b where b.columnC = a.columnA)
where exists (select * from tableb b where b.columnC = a.columnA) and a.columnD = 'ABC'
For the above query i am getting the exception 'Single Row subquery returns more than one row'
update tableA a set a.columnA = b.columnB from tableb b on a.columnA = b.columnC where a.columnD = 'ABC'
For the above query i am getting the exception 'SQL command not properly ended'
update a set a.columnA = b.columnB from tablea a inner join tableb b on a.columnA=b.columnC where a.columnD = 'ABC'
For the above query i am getting the exception 'SQL command not properly ended'
I think your issue is that you have multiple rows in tableB that match ("where b.columnC = a.columnA"). So when you tell Oracle to:
set columnA = (
select b.columnB
from tableb b
where b.columnC = a.columnA)
where exists ...
its finding multiple rows in tableB for a given key value. You'll have to decide how you'd like Oracle to choose just one. For example, if you really don't care which of the multiple values, you could do something like (untested):
set columnA = (
select distinct(max(b.columnB))
from tableb b
where b.columnC = a.columnA)
where exists ...

Oracle join query

I have two tables
Table A has columns id|name|age.
Table B has columns id|name|age.
Sample Records from table A
1|xavi |23
2|christine|24
3|faisal |25
5|jude |27
Sample Records from table B
1|xavi |23
2|christine|22
3|faisal |23
4|ram |25
If id values from table A matches in table B than take records from table A only.
Also take records which are present in table A only
Also take records which are present in table B only
So my result should be
1|xavi |23
2|christine|24
3|faisal |25
4|ram |25
5|jude |27
You can simply use union operator to get unique values from both tables. Operator UNION will remove repeated values.
SELECT * FROM tableA AS t1
UNION
SELECT * FROM tableB AS t2
You have a precedence problem here. Take all the records from table A and then the extra records from table B:
select *
from A
union all
select *
from B
where B.id not in (select A.id from A);
You can also express this with a full outer join (assuming id is not duplicated in either table):
select coalesce(A.id, B.id) as id,
coalesce(A.name, B.name) as name,
coalesce(A.age, B.age) as age
from A full outer join
B
on A.id = B.id;
In this case, the coalesce() gives priority to the values in A.
select distinct * FROM
(
select ID, NAME, AGE from TableA
UNION ALL
select ID, NAME, AGE from TableB
) TableAB
Some things to consider --> Unless you're updating specific tables and the records are the same, it will not matter which table you're viewing the records from (because they're the same...).
If you want to see which table the records are deriving from, let me know and i'll show you how to do that as well... but the query is more complex and i don't really think it's required for the purpose described above. let me know if this helps... thanks, Brian
If the tables has relation you need:
Select DISTINCT *
from tableA a
Inner Join tableB b
On a.id = b.id
If not:
You have to use UNION and after using DISTINCT.
DISTINCT will not permit repeat rows.

How to update a table with null values with data from other table at one time?

I have 2 tables - A and B . Table A has two columns, pkey (primary key) and col1. Table B also has two columns, pr_key (primary key but not a foreign key) and column1. Both tables have 4 rows. Table B has no values in column1, while table A has column1 values for all 4 rows. So my data looks like this
Table A
pkey col1
A 10
B 20
C 30
D 40
Table B
pr_key column1
A null
B null
C null
D null
I want to update table B to set the column1 value of each row equal to the column1 value of the equivalent row from table A in a single DML statement.
Should be something like that (depends on SQL implementation you use, but in general, the following is rather standard. In particular should work in MS-SQL and in MySQL.
INSERT INTO tblB (pr_key, column1)
SELECT pkey, col1
FROM tblA
-- WHERE some condition (if you don't want 100% of A to be copied)
The question is a bit unclear as to the nature of tblB's pr_key, if for some reason this was a default/auto-incremented key for that table, it could just then be omitted from both the column list (in parenthesis) and in the SELECT that follows. In this fashion upon insertion of each new row, a new value would be generated.
Edit: It appears the OP actually wants to update table B with values from A.
The syntax for this should then be something like
UPDATE tblB
SET Column1 = A.Col1
FROM tblA AS A
JOIN tblB AS B ON B.pr_key = A.pkey
This may perform better:
MERGE INTO tableB
USING (select pkey, col1 from tableA) a
ON (tableB.pr_key = a.pkey)
WHEN MATCHED THEN UPDATE
SET tableB.column1 = a.col1;
It sounds like you want to do a correlated update. The syntax for that in Oracle is
UPDATE tableB b
SET column1 = (SELECT a.column1
FROM tableA a
WHERE a.pkey = b.pr_key)
WHERE EXISTS( SELECT 1
FROM tableA a
WHERE a.pkey = b.pr_key )
The WHERE EXISTS clause isn't necessary if tableA and tableB each have 4 rows and have the same set of keys in each. It is much safer to include that option, though, to avoid updating column1 values of tableB to NULL if there is no matching row in tableA.

Resources