我的意思是:
Table PHONE_CODES:
ID CODE_NAME PHONE_CODE
1 USA 8101
2 USA 8102
3 PERU 8103
4 PERU_MOB 81031
5 PERU_MOB 81032
我希望通过select得到这样的东西:
CODE_NAME ZONE_CODES
USA 8101; 8102;
PERU 8103
PERU_MOB 81031; 81032;
我可以通过下面的函数得到它,但也许有更好的方法:
select distinct(CODE_NAME) as CODE_NAME, get_code_names_by_ZONE(CODE_NAME) as ZONE_CODES from PHONE_CODES;
功能:
create or replace function get_code_names_by_ZONE
(
ZONE_CODE_NAME in varchar2
)
return varchar2
as
codes_list varchar2(4000);
cursor cur_codes_list is
select p.PHONE_CODE
from PHONE_CODES p
where p.CODE_NAME = ZONE_CODE_NAME;
begin
for codes_list_rec in cur_codes_list
LOOP
-- dbms_output.put_line('PHONE_CODE:[' || codes_list_rec.PHONE_CODE || ']');
codes_list := codes_list || codes_list_rec.PHONE_CODE || '; ';
end loop;
return codes_list;
EXCEPTION
when NO_DATA_FOUND then
return 'notfound';
WHEN others then
dbms_output.put_line('Error code:' || SQLCODE || ' msg:' || SQLERRM);
return null;
end get_code_names_by_ZONE;
/
答案 0 :(得分:1)
一个功能将是我实现你想要的东西的首选方法。
答案 1 :(得分:1)
答案 2 :(得分:0)
如果您使用的是11g,请查看SQL的新PIVOT扩展 - 最佳文档可以在“数据仓库指南”部分中找到。但我相信“... for in ...”子句的目标不能是子查询,而必须是硬编码的值列表。
答案 3 :(得分:0)
良好的链接贾斯汀。蒂姆大厅太棒了。我听从他的建议,现在是:
1 SELECT CODE_NAME,
2 LTRIM(MAX(SYS_CONNECT_BY_PATH(PHONE_CODES,';'))
3 KEEP (DENSE_RANK LAST ORDER BY curr),';') AS PHONE_CODES
4 FROM (SELECT CODE_NAME,
5 PHONE_CODES,
6 ROW_NUMBER() OVER (PARTITION BY CODE_NAME ORDER BY PHONE_CODES) AS curr,
7 ROW_NUMBER() OVER (PARTITION BY CODE_NAME ORDER BY PHONE_CODES) -1 AS prev
8 FROM a)
9 GROUP BY CODE_NAME
10 CONNECT BY prev = PRIOR curr AND CODE_NAME = PRIOR CODE_NAME
11* START WITH curr = 1
SQL> /
CODE_NAME PHONE_CODES
---------- --------------------------------------------------
PERU 8103
PERU_MOB 81031;81032
USA 8101;8102
dbBradley - 我不认为Pivot扩展在这里工作。 Pivot扩展需要使用聚合(sum,count,...)。