Oracle在多个列中使用ListAgg,不同的值

时间:2016-07-01 15:56:48

标签: sql oracle listagg

for Oracle 12c ...我有一个销售给公司的订单项表。此表具有销售给该公司的销售代表的3层级层次结构。其中一列是公司名称。我需要帮助编写SQL,以便在销售给该公司的所有行中生成所有三个列中所有人的名称的逗号分隔的唯一列表。举个例子...

CompanyName  Rep      Manager     GVP
-----------  -------  --------   --------
Sears        Bob      Tim        Frank
Sears        Jack     Tim        Frank
Ace          Scott    Chris      Bill

当我看到Sears时,SQL应该返回Bob,Jack,Tim,Frank'。名称的ORDER无关紧要,只是它们是唯一的,并且它们包含来自所有3个字段的名称。我会假设这是一种ListAgg查询,但可能是错误的......

3 个答案:

答案 0 :(得分:3)

使用UNPIVOT运算符(它只执行一次表扫描,而使用UNION通常会对联合语句中的每个SELECT执行一次表扫描):

Oracle安装程序

CREATE TABLE table_name ( CompanyName, Rep, Manager, GVP ) AS
SELECT 'Sears', 'Bob',   'Tim',   'Frank' FROM DUAL UNION ALL
SELECT 'Sears', 'Jack',  'Tim',   'Frank' FROM DUAL UNION ALL
SELECT 'Ace',   'Scott', 'Chris', 'Bill'  FROM DUAL;

<强>查询

SELECT CompanyName,
       LISTAGG( Name, ',' ) WITHIN GROUP ( ORDER BY Name ) AS Names
FROM   (
  SELECT DISTINCT
         CompanyName,
         Name
  FROM   table_name
  UNPIVOT( name FOR typ IN ( Rep, Manager, GVP ) )
)
GROUP BY CompanyName;

<强>输出

COMPANYNAME NAMES
----------- ------------------
Ace         Bill,Chris,Scott
Sears       Bob,Frank,Jack,Tim

答案 1 :(得分:2)

您需要取消数据的删除(删除重复项),然后重新集中它:

select companyname, listagg(person, ',') within group (order by person) as persons
from ((select companyname, repfrom as person t) union
      (select companyname, manager from t) union
      (select companyname, gvp from t)
     ) t
group by companyname;

答案 2 :(得分:0)

这个SQL可以解决这个问题:

select listagg(p, ', ') within group (order by p) from (
  select rep p
  from   your_table
  union
  select manager p
  from   your_table
  union
  select gvp p
  from   your_table);