2013-11-13 3 views
2

Это данные в Bar:РЕГИСТРИРУЙТЕСЬ/GROUP выберите ранние

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 Самый ранний occourency ОТ 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 occours.

ответ

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, а затем присоединяется через ид. вне его выбирает только кандидат занимает 1 (самый ранний StartDate)

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

Это РЕГИСТРИРУЙТЕСЬ с MIN (STARTDATE) для каждого FooId.

Если включить дату в запросе это приведет:

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

Хм, это, вероятно, может дать мне дублировать записи в дублированных даты правильные? –

+0

Только если у вас есть дубликаты ID в foo. Внутренний SELECT возвращает только одно значение даты для fooID –

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) 
Смежные вопросы