Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Three table join

I haven't been able to solve this problem for several days now and I'm hoping you can help.

I'm trying to write a query that returns all the information about a stock and the last time it was updated. I would like to filter the results based on the parameter @date and return only the stocks which it's latests update is less than the supplied @date parameter. I also need the stocks with a timestamp of null so I know that theses stocks need to be updated. I have the follwing three tables that I'm working with:

stocks
- id
- asset_id
- market_id
- name
- symbol
- IPOYear
- sector
- industry

updates
- id
- [timestamp]

stock_updates
- stock_id
- update_id

I've been using the following query and it was working well for me until I realized it dosen't work if the stock doesn't have an update

select * from stocks s
where @date < (
    select top 1 u.timestamp from
        updates u,
        stock_updates su
    where
        s.id = su.stock_id and
        u.id = su.update_id
    order by u.timestamp desc
)

So after some research I came accross outer joins and I think it's what I need to fix my problem I just haven't been able to construct the correct query. The closest I've come is the following, but it returns a record for each time the stock was updated. Thanks in advance for your help!

This is where I'm at now:

select * from stocks s 
left outer join stock_updates su on s.id = su.stock_id 
left outer join updates u on u.id = su.update_id 
where u.[timestamp] < @date
like image 277
robson Avatar asked Mar 28 '26 21:03

robson


2 Answers

select s.*, u.timestamp
from stocks s 
left join 
(select  su.stock_id, MAX(u.timestamp) timestamp
from updates u 
inner join stock_updates su 
on u.id = su.update_id
group by su.stock_id
) as u
on s.id = u.stock_id
where u.[timestamp] is null or u.[timestamp] < @date
like image 180
JBrooks Avatar answered Mar 31 '26 03:03

JBrooks


Something like this perhaps?

SELECT s.*, v.timestamp
FROM stocks s
LEFT JOIN (
    SELECT MAX(u.timestamp) AS timestamp, su.stock_id
    FROM stock_updates su
    INNER JOIN updates u ON (u.id = su.update_id)
    GROUP BY su.stock_id
) v ON (v.stock_id = s.stock_id)

Basically it just joins the stocks table to an "inline view" that is the result of a query to determine the maximum timestamp for each stock_id.

like image 26
ninesided Avatar answered Mar 31 '26 05:03

ninesided