2012-02-19 59 views
3

我几天来一直无法解决这个问题,我希望你能帮上忙。SQL三表加入

我想写一个查询,返回有关股票的所有信息和上次更新。我想根据参数@date过滤结果,并只返回最近更新的股票比提供的@date参数少。我还需要时间戳为空的股票,所以我知道这些股票需要更新。我有我的工作的follwing三个表:

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

updates 
- id 
- [timestamp] 

stock_updates 
- stock_id 
- update_id 

我一直在使用以下查询,这是工作很适合我,直到我意识到,如果股票没有它这么想的工作更新

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 
) 

因此,一些研究,我得出翻过外连接,我想这就是我要解决我的问题,我只是一直无法构建正确的查询。我接近的最接近的是以下内容,但每次更新库存时都会返回记录。在此先感谢您的帮助!

这是我在哪里现在:

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 

回答

3
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 
+0

谢谢@jbrooks回复!这几乎可以工作,并且完全按照我在问题中提出的要求,它将使用最新的时间戳返回所有股票,包括时间戳为空。不过,我忽略了添加的问题,我需要添加日期参数来选择只有未通过日期更新的股票。当我取消注释WHERE子句时,出现错误,因此我在“s.id = u.stock_id”之后移动它,并且它返回所有股票的最新时间戳记更新,但前提是它们有时间戳记。 – robson 2012-02-19 01:33:07

+0

谢谢@Jbrooks。现在完美的作品非常感谢! – robson 2012-02-19 02:34:45

1

我还没有包括由@date参数任何过滤,因为你的问题状态

“我想写一个查询返回有关 股票和上次更新的所有信息“

并且因此您不需要y过滤。

这个查询正是这么做的:

select s.*, dr.maxtime, 
from stocks s 
left join (select MAX(u.timestamp) as maxtime, su.stock_id 
      from stock_updates su inner join updates u on u.id = su.update_id 
      group by su.stock_id) dr 
    on dr.stock_id = s.stock_id 
where 
    maxtime < @date or maxtime is null 

[BTW:left join相同left outer join]

+0

我打算添加它,但重新阅读问题海报说:“我试图编写一个查询,返回有关股票的所有信息以及上次更新的时间。 – 2012-02-19 00:31:57

+2

这就是这些碰到的问题 - 没有OP的澄清,很多正确的解决方案,没有人看到他们的努力。真是浪费。 =/ – Yuck 2012-02-19 00:39:17

+0

谢谢@MitchWheat小麦。这与我最初描述的完全一样,但我需要添加一个WHERE子句,它将仅返回最后一次更新的股票在提供的日期参数之前。当我在dr之后添加WHERE dr.maxtime <日期时。stock_id = s.stock_id它正确过滤,但不包括时间戳为null的股票。非常感谢你的帮助。 – robson 2012-02-19 01:30:59

2

像这样的事情吧?

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) 

基本上它只是加入stocks表“内联视图”,也就是一个查询的结果来确定每个stock_id最大timestamp

+0

@@ Yuck:这不是OP问题所陈述的...... – 2012-02-19 00:35:38

+0

@Yuck:...并且完全不必要。我假设他们错误地创造了它。 – 2012-02-19 00:38:47

+0

@MitchWheat哈哈我也这么做了。 – Yuck 2012-02-19 00:42:38

0

试试这个

select s.*, max(su.timestamp) 
from 
    stocks s 
     left outer join 
    stock_update su 
     on (s.id = su.stock_id) 
     left outer join 
    updates u 
     on (u.id = su.update_id) 
group by s.* 

这是写了我的头顶。你指什么@date?这是否意味着“现在”?你的意思是最新的时间戳,还是最近的@date