JOIN / GROUP选择最早

时间:2013-11-13 12:34:49

标签: sql oracle

这是Bar中的数据:

ID     FooID    StartDate
1        1         1-1-2011
2        1         2-1-2011
3        1         3-1-2011
4        2         9-1-2011
5        2         4-1-2011

这是表Foo

ID   Name
1        Car
2        Bus  

我需要LEFT JOIN最早的封闭性来自Foo

这就是我现在所拥有的:

SELECT NAME
FROM Foo
LEFT JOIN (
  SELECT *
  FROM Bar
  WHERE Bar.FooID = Foo.ID
  ORDER BY Bar.StartDate
  ) MyBar
  ON (ROWNUM = 1)

但是ORA-00923会出现。

3 个答案:

答案 0 :(得分:1)

我不太确定你在这里要做什么,但我认为你不能加入rownum,也不能从内部选择中解决foo.id。我可以给你这种方法,我认为应该这样做:

select name
  from foo
  left join (
              select bar.*
                   , dense_rank() over (order by bar.startdate) as cand
                from bar
            ) mybar
    on (mybar.fooid = foo.id)
 where mybar.cand = 1

它首先按照startdate从bar开始对条目进行排名,然后通过id加入。在它之外只选择排名第一的候选人(最早的开始日期)

答案 1 :(得分:1)

试试这个:

SELECT NAME
FROM foo b
LEFT JOIN (
  SELECT FooID,MIN(StartDate)
  FROM bar
  GROUP BY FooID
  ) MyBar
  ON MyBar.FooId = b.ID

sqlfiddle demo

这将为每个FooId加入MIN(startDate)。

如果在查询中包含日期,则会产生:

NAME   FOODATE
Car    January, 01 2011 00:00:00+0000
Bus    April, 01 2011 00:00:00+0000

答案 2 :(得分:1)

SQLFiddle demo

select * from Foo
LEFT JOIN
(
  SELECT  BAR.*,
          ROW_NUMBER() 
          OVER (PARTITION BY FooID 
                ORDER BY StartDate) as RowNumber
   FROM BAR 
 ) Bar2 on (Foo.id=Bar2.FooId) and (Bar2.RowNumber=1)