2013-02-21 4 views
5

у меня есть три таблицы, как показано ниже:левое внешнее присоединение трех таблиц в оракула

enter image description here

И я пытаюсь получить выход, как показано ниже:

enter image description here

Вот что я до сих пор пробовали

SELECT table1.tb1_a, 
CASE WHEN table3.tb3_a IS NOT NULL THEN 
    tb3_b 
    ELSE 'No city for him yet' 
END AS 'City' 
FROM table1 
LEFT OUTER JOIN table2 ON 
    table1.tb1_a = table2.tb2_a 
LEFT OUTER JOIN table3 ON 
    table2.tb2_a = table3.tb3_a 
WHERE table3.tb3_a IN 
    (

    ) 

А теперь я борюсь о том, как выбрать максимальное значение столбца tb3_a

+0

Я думаю, что может запутать людей в том, что я думаю, что вы на самом деле хотите, максимальное значение 'tb2_b' а затем присоедините это к 'tb3_a'. – ninesided

+0

Я думаю, что в вашей текущей попытке есть ошибка. Вы сравниваете tb2_a с tb3_a. Похоже, вы должны сравнивать tb2_b с tb3_a. –

+0

@Walter - вы правы, см. Мой пример ниже – ninesided

ответ

2

Это должно делать то, что вам нужно:

SELECT t1.tb1_a, COALESCE(t3.tb3_a, 'No city for him yet') AS City 
FROM table1 t1 
LEFT JOIN (
    SELECT MAX(tb2_b) AS tb2_b, tb2_a 
    FROM table2 
    GROUP BY tb2_a 
) t2 ON (t2.tb2_a = t1.tb1_a) 
LEFT JOIN table3 t3 ON (t3.tb3_a = t3.tb2_b); 

Ключевым моментом является вид в линию в середине, где мы создаем своего рода виртуальный таблица, которая содержит максимальное значение tb2_b для каждого tb2_a. Затем мы можем присоединиться к этому, чтобы достичь желаемого результата.

+0

Привет, Большое спасибо за ответ и за ваше время. – javanoob

+0

@javanoob - вас больше всего приветствуют – ninesided

1

Что-то, как это должно работать

select tb1_a, nvl(max(city), 'no city for him yet') thecity 
from etc 
group by tbl_a 
1

Я думаю, что вы хотите сделать это с помощью аналитических функций. Вот как:

SELECT tb1_a, coalesce(tb3_b, 'No city for him yet') as City 
from (select table1.tb1_a, tb3_b, 
      ROW_NUMBER() over (partition by table1.tbl1_a order by tb3_a desc) as seqnum 
     FROM table1 LEFT OUTER JOIN 
      table2 
      ON table1.tb1_a = table2.tb2_a LEFT OUTER JOIN 
      table3 
      ON table2.tb2_a = table3.tb3_a 
    ) t 
where seqnum = 1 

Это использует row_number() определить последнюю запись в Table3. Это выбирается по предложению where seqnum = 1.

+0

Спасибо, это помогает – javanoob

0

попробовать это, надеюсь, вы поможете

with table_1 as 
(select 10 as tb1_a, 'John' as tb1_b 
    from dual 
    union all 
    select 20 as tb1_a, 'John1' as tb1_b 
    from dual 
    union all 
    select 30 as tb1_a, 'John2' as tb1_b from dual), 
table_2 as 
(select 10 as tb2_a, 100 as tb2_b 
    from dual 
    union all 
    select 10 as tb2_a, 1000 as tb2_b 
    from dual 
    union all 
    select 10 as tb2_a, 10000 as tb2_b 
    from dual 
    union all 
    select 20 as tb2_a, 200 as tb2_b 
    from dual 
    union all 
    select 20 as tb2_a, 2000 as tb2_b 
    from dual 
    union all 
    select 20 as tb2_a, 20000 as tb2_b from dual), 
table_3 as 
(select 100 as tb3_a, 'City1' as tb3_b 
    from dual 
    union all 
    select 1000 as tb3_a, 'City10' as tb3_b 
    from dual 
    union all 
    select 10000 as tb3_a, 'City100' as tb3_b 
    from dual 
    union all 
    select 200 as tb3_a, 'City2' as tb3_b 
    from dual 
    union all 
    select 2000 as tb3_a, 'City20' as tb3_b 
    from dual 
    union all 
    select 20000 as tb3_a, 'City200' as tb3_b from dual) 

select user_id, city 
    from (select u.tb1_a as user_id, 
       nvl(c.tb3_b, 'No city') as city, 
       rank() over(partition by u.tb1_a order by tb3_a) as city_rank 
      from table_1 u, table_2 u_c, table_3 c 
     where u.tb1_a = u_c.tb2_a(+) 
      and u_c.tb2_b = c.tb3_a(+)) t1 
where city_rank = 1 
1

Это работает:

http://sqlfiddle.com/#!4/7ba1c/12

SELECT table1.tb1_a, 
     CASE WHEN table3.tb3_a IS NOT NULL THEN tb3_b 
      ELSE 'No city for him yet' 
     END AS City, 
table2.*, table3.* 
FROM table1 
LEFT OUTER JOIN table2 ON table1.tb1_a = table2.tb2_a 
LEFT OUTER JOIN table3 ON table2.tb2_b = table3.tb3_a 
where tb2_b = (select max(tb2_b) 
       from table2 t22 
       where t22.tb2_a = tb1_a) 
or tb2_b is null 
order by 1 

Я думаю, где положение объясняет себя

+0

Это замечательно .. Я понял, где я делал неправильно быстро. Спасибо тонну, чтобы подготовить столы и все на sqlfiddle. – javanoob

+0

@Juergen, в то время как ваш запрос может вернуть правильные результаты, наличие коррелированного подзапроса в предложении 'WHERE' может стать очень дорогостоящим, поскольку подзапрос должен быть выполнен один раз для каждой строки, возвращаемой результирующим набором. – ninesided

Смежные вопросы