Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在一个字段中组合分组值的简单方法是什么?_Sql_Oracle_Plsql - Fatal编程技术网

Sql 在一个字段中组合分组值的简单方法是什么?

Sql 在一个字段中组合分组值的简单方法是什么?,sql,oracle,plsql,Sql,Oracle,Plsql,我的意思是: 我想通过select获得如下信息: 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 我可以通过下面的函数获得它,但也许有更好的方法: CODE_NAME ZONE_CODES USA 8101; 8102;

我的意思是:

我想通过select获得如下信息:

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
我可以通过下面的函数获得它,但也许有更好的方法:

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;

函数将是我实现所需功能的首选方法。

Tim Hall对Oracle中提供的各种功能进行了出色的讨论

如果您使用的是11g,请看一看SQL的新PIVOT扩展—最好的文档应该在《数据仓库指南》一节中。然而,我相信“…for in…”子句的目标不能是子查询,必须是一个硬编码的值列表。

好链接Justin。蒂姆·霍尔太棒了。我听从了他的建议,下面是:

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

布拉德利-我认为Pivot扩展在这里不起作用。Pivot扩展需要使用聚合(总和、计数等)

我使用了收集方法——在我看来,这是最好、最快的选择。从电话号码中选择电话号码、制表符到字符串(按t_varchar2_制表符转换(收集完整电话号码),“;”)作为cdf,其中CONNECT_BY_ISLEAF=1 CONNECT BY previous PHONE_CODE_id=par_PHONE_CODE_id group BY PHONE_CODE;我喜欢它,除了需要创建对象类型。如果你经常使用它,这不是一件坏事。我只是不喜欢在DB中添加不需要的对象。少记录,记住,稍后清理;-)
  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