Reputation: 331
this is a question for plsql & oracles. I am new to this. Please help!
I have 2 tables: Table A and Table B
Table A: ID, Date
Table B: Name, Address
How do I do a join between 2 tables and then have it just return based on latest date. Also, it will be based on specified ID in a list.
My current query returns this:
1 | 1/1/2013 | Apple | 123 Malcolm
1 | 1/2/2013 | Apple | 123 Malcolm
1 | 1/3/2013 | Apple | 123 Malcolm
3 | 1/1/2013 | Orange| 124 Malcolm
3 | 1/2/2013 | Orange| 124 Malcolm
How do I get it to return just:
1 | 1/3/2013 | Apple | 123 Malcolm
3 | 1/2/2013 | Orange| 124 Malcolm
select unique(ID), a.Date, b.Name, b.Address
from tableA a
join tableB b
on a.ID = b.ID
where a.Date > TO_DATE('12/31/2012', 'mm/dd/yyyy') and a.ID in ('1', '3')
Thanks!
Upvotes: 0
Views: 1129
Reputation: 3303
Using Analytical functions like RANK() will be the best option.
Upvotes: 0
Reputation: 5636
Here's a fast and simple solution. I assume that ID and Date in TableA form the PK, so are indexed. The subquery finds the Max date for the specified ID and does it quickly due to the index. That record is then used to join to TableB. I use this format all the time when looking through a sequence of dates to find the latest (Max), or earliest (Min). You'll find it acceptably fast even if TableA is very large.
with
TableA as (
select 1 id, date '2013-01-01' selected from dual union all
select 1, date '2013-01-02'from dual union all
select 1, date '2013-01-03'from dual union all
select 3, date '2013-01-01' from dual union all
select 3, date '2013-01-02' from dual
),
TableB as (
select 1 id, 'Apple' name, '123 Malcolm' addr from dual union all
select 3, 'Orange', '124 Malcolm' from dual
)
-- Here is the query:
select *
from TableB b
join TableA a
on a.id = b.id
and a.selected =(
select Max( selected )
from TableA
where id = a.id
);
Upvotes: 0
Reputation: 1594
This way uses analytics:
select a_id,
a_date,
b_name,
b_address
from (
select a.id as a_id,
a.date as a_date,
b.name as b_name,
b.address as b_address,
rank() over (partition by a.name_id
order by a.date desc) as rnk
from a inner join b on a.id=b.id
where a.id in ('1','3') and
a.date > to_date('12/31/2013','mm/dd/yyyy')
)
where rnk=1
Upvotes: 1
Reputation: 2864
You need to group
your result set. Also you need an aggregat function, in this case MAX()
This should work:
select unique(ID), MAX(a.Date), b.Name, b.Address
from tableA a
join tableB b
on a.ID = b.ID
where a.Date > TO_DATE('12/31/2012', 'mm/dd/yyyy') and a.ID in ('1', '3')
group by ID, b.Name, b.Address
You can read up on those methods and more over at http://www.w3schools.com/sql
Link to the GROUP BY
explanation: http://www.w3schools.com/sql/sql_groupby.asp
Link to the MAX()
explanation: http://www.w3schools.com/sql/sql_func_max.asp
Upvotes: 3
Reputation: 35323
There's lots of ways to do this:
This is one. It gets a subset of max dates by the ID and then joins it into what you have already thereby limiting to the max of each group.
Select A.ID, A.Date, B.Name, B.Address
FROM A
INNER JOIN B
on A.ID = B.ID
INNER JOIN (Select max(date) maxDate, ID from A group by ID) C
on C.ID=A.ID and C.MaxDate = A.Date
WHERE
A.ID IN ('1','3')
Upvotes: 2