I mean:
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
And I want via select to get something like this:
CODE_NAME   ZONE_CODES
USA          8101; 8102;
PERU         8103
PERU_MOB     81031; 81032;
I could get it via the function below, but perhaps there is a better way:
select distinct(CODE_NAME) as CODE_NAME, get_code_names_by_ZONE(CODE_NAME) as ZONE_CODES from PHONE_CODES;
Function:
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;
/