2010-11-10 36 views
7

Tôi đã viết một giải pháp cho vấn đề bằng cách sử dụng PL/SQL và SQL và tôi không thể không nghĩ rằng nó có thể được thực hiện 100% trong SQL nhưng tôi đang đấu tranh để bắt đầu.Giải pháp cho vấn đề được thực hiện trong PL/SQL nó sẽ trông như thế nào trong SQL?

Dưới đây là cấu trúc của hai bảng (Nếu nó giúp, các kịch bản để tạo ra chúng là ở phần cuối của câu hỏi)

Bảng t1 (khóa chính là cả hai cột hiển thị)

ID TYPE 
1  A 
1  B 
1  C 

2  A 
2  B 

3  B 

các cột Type là một khóa ngoại đến bảng T2, trong đó có các dữ liệu sau:

bảng t2 (khóa chính là Type)

Type Desc 
A  xx 

B  xx 

C  xx 

Vì vậy, cho các dữ liệu trong T1 kết quả tôi cần sẽ là:

Đối với ID 1 vì nó có tất cả các loại trong bảng ngoại quan trọng tôi sẽ trả lại đen "Tất cả"

Đối với ID 2 bởi vì nó có hai loại tôi muốn trở về "A B &" (lưu ý các dấu phân cách)

Và cuối cùng cho ID 3 bởi vì nó có một loại tôi muốn quay trở lại chỉ là "B"

Như đã hứa ở đây là các kịch bản để tạo tất cả các đối tượng được đề cập.

create table t2(type varchar2(1), 
       description varchar2(100) 
       )     
/

insert into t2 
values ('A', 'xx') 
/

insert into t2 
values ('B', 'xx') 
/

insert into t2 
values ('C', 'xx') 
/

alter table t2 add constraint t2_pk primary key (type) 
/

create table t1 (id number(10), 
       type varchar2(1) 
       ) 
/

alter table t1 add constraint t1_pk primary key(id, type) 
/

alter table t1 add constraint t1_fk foreign key (type) 
references t2(type) 
/

insert into t1 
values (1, 'A') 
/

insert into t1 
values (1, 'B') 
/

insert into t1 
values (1, 'C') 
/

insert into t1 
values (2, 'A') 
/

insert into t1 
values (2, 'B') 
/

insert into t1 
values (3, 'B') 
/
+0

Bạn sẽ thêm nhiều loại khác vào t2? Không chỉ A, B, và C? – mcpeterson

+0

@mcpeterson: Cảm ơn nhận xét. Các dữ liệu trong t2 sẽ được cố định, với tổng số khoảng 5 hàng –

+1

Sự cần thiết phải nối chuỗi nhóm theo định hướng phủ nhận khả năng thực hiện điều này trong SQL thuần túy. –

Trả lời

5

Something như thế này sẽ giúp bạn có những gì bạn đang tìm kiếm:

select 
    id, 
    case 
     when cnt = (select count(distinct type) from t2) 
     then 'All' 
     else ltrim(sys_connect_by_path(type,' & '),' &') 
    end types 
from (
    select 
     t1.id, 
     t2.type, 
     count(*) over (partition by t1.id) cnt, 
     row_number() over (partition by t1.id order by t2.type) rn 
    from 
     t1 
     inner join t2 
      on t2.type = t1.type 
) 
where 
    rn = cnt 
    start with rn = 1 
    connect by prior id = id and prior rn = rn-1; 

tôi sẽ cung cấp cho câu hỏi của bạn 10 nếu tôi có thể cho đăng đối tượng/tạo dữ liệu kịch bản của bạn!

+1

Sẽ không phải là 'GROUP BY Type' và một hàm tổng hợp thay vì sys_connect_by_path là đủ? –

+3

Có, bạn có thể nhận được cùng một giải pháp nếu bạn tạo một hàm tổng hợp tùy chỉnh mà bạn gọi với một nhóm theo (tương tự như hàm stragg khá phổ biến). Tất nhiên đó không phải là "chỉ SQL" nữa mặc dù ... :) – Craig

+3

Nếu bạn có 11g, bạn có thể sử dụng chức năng phân tích LISTAGG thay vì: http://download.oracle.com/docs/cd/E11882_01/server.112 /e17118/functions089.htm –

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