Oracle join query - oracle

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.

Related

Oracle: Joining two table with a common column plus a additional column(latest effective date) from second table to select other column

Joining two table with a common column plus an additional column (latest effective date) from the second table to select another column. I joined the tables with all conditions, but the resulting table has duplicate records as there are multiple records in Table2 for the same identifier, out of which I just need the record with the latest effective date. I am using Oracle.
Table1 (Column A, B, C, D);Table2 (C, Efft_date, X),Table3...
The result should be as below after Joining the tables: A, B, C, X and columns from other tables
Value of X depends on latest/max value of efft_date from Table2.
Other Info: There are other tables that are joined and other conditions in where clause.
Please help to join the tables without duplicates
So you need to further restrict your result set based on the max of table2.efft_date. So you need a clause like:
AND table2.efft_date = ( SELECT MAX( table2b.efft_date)
FROM table2 AS table2b
WHERE table2b.c = table2.c )
This assumes that table2 cannot have duplicate efft_date values.
You need to join to a subquery so that you get just 1 "latest date" for each value of column c. For this I recommend using row_number()
select t1.A, t1.B, t1.C, t1.D, t2.x, t2.efft_date
from table1 t1
inner join (
select c, x, efft_date, row_number() over(partition by c order by efft_date DESC) as rn
from table2
) t2 on t1.c = t2.c and t2.rn = 1
...
Note that by ordering the dates in descending values, the most recent date will be assigned the row number of 1. Hence the join condition and rn = 1 will only allow the most recent dates to be included in the result.
Changing the order to ascending date order would do the revers, just allow the earliest dates.

ORACLE Query to find value in other table based on dates

I have two tables, Table A has an ID and an Event Date and Table B has an ID, a Description and an Event Date.
Not all IDs in Table A appear in Table B and some IDs appear multiple times in Table B with different Descriptions for each event.
The Description in Table B is an attribute that can change over time, the Event date in Table B is the date that a given ID's Description changes from its default value (kept in another table) to the new value.
I want to find the Description in Table B that matches the Event Date in Table A so, for example
Table Sample Data
A1234 would return Green and A4567 would return Null
I can't create tables here so I need to be able to this with a query.
This query will select last description from before the event:
SELECT * FROM (
SELECT tabA.id, tabA.event_date, tabB.description,
ROW_NUMBER() OVER(PARTITION BY tabB.id ORDER BY tabB.event_date DESC) rn
FROM Table_A tabA
LEFT JOIN Table_B tabB ON tabA.id = tabB.id AND tabB.event_date <= tabA.event_date
) WHERE rn = 1
If I understand well your need, this could be a way:
select a.id, description
from tableA A
left join
(select id,
description,
event_date from_date,
lead(event_date) over (partition by id order by event_date) -1 as to_date
from tableB
) B
on (A.id = B.id and a.event_date between b.from_date and b.to_date)
The idea here is to evaluate, for each row in tableB the range of dates for which that row, and its description, is valid; given this, a simple join should do the job.
You can left join tables like:
select a.ID , b1.DESCRIPTION
from TABLE_A a
left join TABLE_B b1 on a.ID = b1.id and a.EVENT_DATE > b1.EVENT_DATE
left join TABLE_B b2 on a.ID = b2.id and b1.EVENT_DATE < b2.EVENT_DATE and a.EVENT_DATE > b2.EVENT_DATE
where b1.id is null or b2.EVENT_DATE is null;

how to find the table row count in hive query using group by

Here my question: I have a table with some records like (name, date, type). Suppose I have three type a, b and c.Now I want to count percentage of each type mean COUNT(type)/COUNT(table row count)??
select type,COUNT(type) as counttype,counttype/(select COUNT(*) from xyz) from xyz group by xyz;
"(select COUNT(*) from xyz)" this giving me error.
How to find the table Row Count?
You can use below query :-
select A.type,A.type_cnt,(A.type_cnt/B.total_cnt) from
(Select type,count(type) as type_cnt from xyz group by type)A
JOIN
(select count(*)as total_cnt from xyz)B
ON 1=1;
Without JOIN it is much faster, using analytic function:
select type,
count(type) as type_cnt,
count(type)/count(*) over() as pct
from xyz
group by type;

why this two select statement doesnt' give same answer

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.

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