2013-02-21 32 views
5

Tôi có ba bảng như hình dưới đây:trái bên ngoài tham gia ba bảng trong oracle

enter image description here

Và tôi đang cố gắng để có được kết quả như dưới đây:

enter image description here

Dưới đây là những gì tôi đã thử đến bây giờ

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 
    (

    ) 

Và bây giờ tôi đang gặp khó khăn về cách chọn giá trị tối đa của cột tb3_a

+0

Tôi nghĩ rằng những gì có thể nhầm lẫn giữa người dân ở đây là tôi nghĩ rằng bạn thực sự muốn giá trị lớn nhất của 'tb2_b' và sau đó nối nó với 'tb3_a'. – ninesided

+0

Tôi nghĩ có một sai lầm trong nỗ lực hiện tại của bạn. Bạn so sánh tb2_a với tb3_a. Có vẻ như bạn nên so sánh tb2_b với tb3_a. –

+0

@Walter - bạn thấy đúng ví dụ của tôi dưới đây – ninesided

Trả lời

2

này nên làm những gì bạn cần:

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); 

Điểm mấu chốt là quan điểm in-line ở giữa nơi mà chúng tôi tạo ra một loại ảo bảng chứa giá trị tối đa tb2_b cho mỗi tb2_a. Sau đó, chúng tôi có thể tham gia để đạt được kết quả mong muốn.

+0

Xin chào, Cảm ơn bạn rất nhiều vì câu trả lời và thời gian của bạn .. – javanoob

+0

@javanoob - bạn được chào đón nhất – ninesided

1

Something như thế này nên làm việc

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

Tôi nghĩ rằng bạn muốn làm điều này với các chức năng phân tích. Dưới đây là cách thực hiện:

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 

Điều này sử dụng row_number() để xác định mục nhập cuối cùng trong bảng 3. Điều này được chọn theo mệnh đề where seqnum = 1.

+0

Cảm ơn điều này sẽ giúp – javanoob

0

thử này, hy vọng bạn giúp

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

này hoạt động:

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 

Tôi nghĩ rằng mệnh đề where giải thích bản thân

+0

Điều này thật tuyệt vời..Tôi hiểu nơi tôi đã làm sai một cách nhanh chóng .. Cảm ơn một tấn để chuẩn bị các bảng và tất cả mọi thứ trên sqlfiddle. – javanoob

+0

@Juergen, trong khi truy vấn của bạn có thể trả lại kết quả chính xác, có truy vấn con tương quan trong mệnh đề 'WHERE' có thể rất tốn kém vì truy vấn con phải được thực hiện một lần cho mỗi hàng được trả về bởi tập kết quả. – ninesided

Các vấn đề liên quan