PLSQL 10g-创建字符串列表

PLSQL 10g-创建字符串列表,sql,oracle,plsql,oracle10g,Sql,Oracle,Plsql,Oracle10g,我已经研究这个有一段时间了。我在下面有一个数据集,我需要将所需的输出放在字符串列表中。如果有一个重复的产品,我希望它去一个单独的行。下面让我看到的是一条线上所有的客户ID和产品。我想知道是否有复制品,请在线复制。如果有任何问题,请告诉我 With CustomerData as ( select ROW_NUMBER() OVER (PARTITION BY customerid ORDER BY Product) rn, COUNT(*) OVER (PARTITION BY customer

我已经研究这个有一段时间了。我在下面有一个数据集,我需要将所需的输出放在字符串列表中。如果有一个重复的产品,我希望它去一个单独的行。下面让我看到的是一条线上所有的客户ID和产品。我想知道是否有复制品,请在线复制。如果有任何问题,请告诉我

With CustomerData as (
select
ROW_NUMBER() OVER (PARTITION BY customerid ORDER BY Product) rn,
COUNT(*) OVER (PARTITION BY customerid ) cnt
from Customers)
select 
ltrim(sys_connect_by_path(customerid,','),','),
ltrim(sys_connect_by_path(Product,','),',') AS Product,
from CustomerData 
where rn = cnt 
start with rn = 1 
connect by prior customerid = customerid
and prior rn = rn1 


customerid | CustomerName | Product | date 
1            Bob            9         3-14-2016
1            Bob            10        3-14-2016       
1            Bob            9         3-12-2016
2            Brad           1         3-14-2016
2            Brad           3         3-14-2016
3            Sam            1         3-14-2016
3            Sam            1         3-12-2016
3            Sam            5         3-14-2016
期望输出

customerid   CustomerName      Product   
1, 1         BOB, BOB         9, 10
1,           BOB              9
2, 2         Brad, Brad       1, 3
3, 3         Sam, Sam         1, 5
3            Sam              1

在Oracle 10上,您应该能够使用wmsys.wm_concat函数,但请注意返回数据类型是CLOB而不是varchar:

WITH the_Data as (
select 1 cust_id,           'Bob' cust_name,           9 prod_id,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 1,            'Bob',            10,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all       
select 1,            'Bob',            9,        to_Date('3-12-2016','mm-dd-yyyy') order_dt from dual union all
select 2,            'Brad',           1,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 2,            'Brad',           3,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            1,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            1,        to_Date(' 3-12-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            5,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual 
)
select wm_concat(cust_id)
      ,wm_concat(cust_name)
      ,wm_concat(prod_id) 
 from the_Data
group by order_dt, cust_id
order by cust_id, order_Dt  

WM_CONCAT(CUST_ID),WM_CONCAT(CUST_NAME),WM_CONCAT(PROD_ID)
1                 Bob                  9
1,1               Bob,Bob              9,10
2,2               Brad,Brad            1,3
3                 Sam                  1
3,3               Sam,Sam              1,5
如果您无权访问此功能(它不是受支持的功能,也不总是安装的),则可以实现

除此之外,您还可以选择进行XML处理:

WITH the_Data as (
select 1 cust_id,           'Bob' cust_name,           9 prod_id,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 1,            'Bob',            10,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all       
select 1,            'Bob',            9,        to_Date('3-12-2016','mm-dd-yyyy') order_dt from dual union all
select 2,            'Brad',           1,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 2,            'Brad',           3,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            1,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            1,        to_Date(' 3-12-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            5,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual 
)
select rtrim(xmlagg(xmlelement(e,cust_id,',').extract('//text()')),',') cus_ids
      ,rtrim(xmlagg(xmlelement(e,cust_name,',').extract('//text()')),',') cus_names
      ,rtrim(xmlagg(xmlelement(e,prod_id,',').extract('//text()')),',') prod_ids
 from the_Data
group by order_dt, cust_id
order by cust_id, order_Dt ;

cus_ids,      cus_names,    prod_ids    
1             Bob           9
1,1           Bob,Bob       9,10
2,2           Brad,Brad     1,3
3             Sam           1
3,3           Sam,Sam       1,5

在Oracle 10上,您应该能够使用wmsys.wm_concat函数,但请注意返回数据类型是CLOB而不是varchar:

WITH the_Data as (
select 1 cust_id,           'Bob' cust_name,           9 prod_id,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 1,            'Bob',            10,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all       
select 1,            'Bob',            9,        to_Date('3-12-2016','mm-dd-yyyy') order_dt from dual union all
select 2,            'Brad',           1,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 2,            'Brad',           3,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            1,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            1,        to_Date(' 3-12-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            5,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual 
)
select wm_concat(cust_id)
      ,wm_concat(cust_name)
      ,wm_concat(prod_id) 
 from the_Data
group by order_dt, cust_id
order by cust_id, order_Dt  

WM_CONCAT(CUST_ID),WM_CONCAT(CUST_NAME),WM_CONCAT(PROD_ID)
1                 Bob                  9
1,1               Bob,Bob              9,10
2,2               Brad,Brad            1,3
3                 Sam                  1
3,3               Sam,Sam              1,5
如果您无权访问此功能(它不是受支持的功能,也不总是安装的),则可以实现

除此之外,您还可以选择进行XML处理:

WITH the_Data as (
select 1 cust_id,           'Bob' cust_name,           9 prod_id,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 1,            'Bob',            10,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all       
select 1,            'Bob',            9,        to_Date('3-12-2016','mm-dd-yyyy') order_dt from dual union all
select 2,            'Brad',           1,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 2,            'Brad',           3,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            1,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            1,        to_Date(' 3-12-2016','mm-dd-yyyy') order_dt from dual union all
select 3,            'Sam',            5,        to_Date('3-14-2016','mm-dd-yyyy') order_dt from dual 
)
select rtrim(xmlagg(xmlelement(e,cust_id,',').extract('//text()')),',') cus_ids
      ,rtrim(xmlagg(xmlelement(e,cust_name,',').extract('//text()')),',') cus_names
      ,rtrim(xmlagg(xmlelement(e,prod_id,',').extract('//text()')),',') prod_ids
 from the_Data
group by order_dt, cust_id
order by cust_id, order_Dt ;

cus_ids,      cus_names,    prod_ids    
1             Bob           9
1,1           Bob,Bob       9,10
2,2           Brad,Brad     1,3
3             Sam           1
3,3           Sam,Sam       1,5

如果不使用未记录的(且不受支持的)
WMSYS.WM_CONCAT
功能(并非所有系统上都可用,并且是),您可以使用集合和
集合
聚合功能来完成

Oracle安装程序

CREATE OR REPLACE TYPE VARCHAR2s_Table AS TABLE OF VARCHAR2(4000);
/

CREATE OR REPLACE FUNCTION concatStrings(
  Strs VARCHAR2s_Table,
  delim VARCHAR2 DEFAULT ','
) RETURN CLOB
AS
  out_string CLOB;
BEGIN
  FOR i IN 1 .. Strs.COUNT LOOP
    out_string := out_string || CASE WHEN i = 1 THEN '' ELSE delim END || Strs(i);
  END LOOP;
  RETURN out_string;
END;
/
CUST_IDS              CUST_NAMES            PROD_IDS
--------------------- --------------------- ---------------------
1                     Bob                   9
1,1                   Bob,Bob               9,10
2,2                   Brad,Brad             1,3  
3                     Sam                   1
3,3                   Sam,Sam               1,5
查询

SELECT concatStrings( CAST( COLLECT( TO_CHAR( cust_id ) ) AS VARCHAR2s_Table ) ) AS cust_ids,
       concatStrings( CAST( COLLECT( cust_name ) AS VARCHAR2s_Table ) ) AS cust_names,
       concatStrings( CAST( COLLECT( TO_CHAR( prod_id ) ) AS VARCHAR2s_Table ) ) AS prod_ids
FROM   table_name
GROUP BY cust_id, order_dt;
输出

CREATE OR REPLACE TYPE VARCHAR2s_Table AS TABLE OF VARCHAR2(4000);
/

CREATE OR REPLACE FUNCTION concatStrings(
  Strs VARCHAR2s_Table,
  delim VARCHAR2 DEFAULT ','
) RETURN CLOB
AS
  out_string CLOB;
BEGIN
  FOR i IN 1 .. Strs.COUNT LOOP
    out_string := out_string || CASE WHEN i = 1 THEN '' ELSE delim END || Strs(i);
  END LOOP;
  RETURN out_string;
END;
/
CUST_IDS              CUST_NAMES            PROD_IDS
--------------------- --------------------- ---------------------
1                     Bob                   9
1,1                   Bob,Bob               9,10
2,2                   Brad,Brad             1,3  
3                     Sam                   1
3,3                   Sam,Sam               1,5

如果不使用未记录的(且不受支持的)
WMSYS.WM_CONCAT
功能(并非所有系统上都可用,并且是),您可以使用集合和
集合
聚合功能来完成

Oracle安装程序

CREATE OR REPLACE TYPE VARCHAR2s_Table AS TABLE OF VARCHAR2(4000);
/

CREATE OR REPLACE FUNCTION concatStrings(
  Strs VARCHAR2s_Table,
  delim VARCHAR2 DEFAULT ','
) RETURN CLOB
AS
  out_string CLOB;
BEGIN
  FOR i IN 1 .. Strs.COUNT LOOP
    out_string := out_string || CASE WHEN i = 1 THEN '' ELSE delim END || Strs(i);
  END LOOP;
  RETURN out_string;
END;
/
CUST_IDS              CUST_NAMES            PROD_IDS
--------------------- --------------------- ---------------------
1                     Bob                   9
1,1                   Bob,Bob               9,10
2,2                   Brad,Brad             1,3  
3                     Sam                   1
3,3                   Sam,Sam               1,5
查询

SELECT concatStrings( CAST( COLLECT( TO_CHAR( cust_id ) ) AS VARCHAR2s_Table ) ) AS cust_ids,
       concatStrings( CAST( COLLECT( cust_name ) AS VARCHAR2s_Table ) ) AS cust_names,
       concatStrings( CAST( COLLECT( TO_CHAR( prod_id ) ) AS VARCHAR2s_Table ) ) AS prod_ids
FROM   table_name
GROUP BY cust_id, order_dt;
输出

CREATE OR REPLACE TYPE VARCHAR2s_Table AS TABLE OF VARCHAR2(4000);
/

CREATE OR REPLACE FUNCTION concatStrings(
  Strs VARCHAR2s_Table,
  delim VARCHAR2 DEFAULT ','
) RETURN CLOB
AS
  out_string CLOB;
BEGIN
  FOR i IN 1 .. Strs.COUNT LOOP
    out_string := out_string || CASE WHEN i = 1 THEN '' ELSE delim END || Strs(i);
  END LOOP;
  RETURN out_string;
END;
/
CUST_IDS              CUST_NAMES            PROD_IDS
--------------------- --------------------- ---------------------
1                     Bob                   9
1,1                   Bob,Bob               9,10
2,2                   Brad,Brad             1,3  
3                     Sam                   1
3,3                   Sam,Sam               1,5


我不能在10 g上运行LISTAGG函数可以在以下Oracle/PLSQL版本中使用:•Oracle 12c,Oracle 11g版本2在10g中有一种未经证明的方法称为
wm_concat()
可能重复的I cant I在10 g上运行Listag函数可用于以下版本的Oracle/PLSQL:•Oracle 12c,Oracle 11g Release 2in 10g中有一种未记录的方法,称为
wm_concat()
可能重复的I看到您正在对数据进行选择。将有更多的数据,我真的只知道列名。有没有办法在没有指定数据的情况下选择cust_id、cust_name、prod_id?with the_data AS()只是我在内存中构建临时表的一种方法。你只需要像平常一样查询你的表。def可以处理示例数据,只需一个查询,它确实会有点不对劲,但我确信这正是我正在做的事情。如果你可以按照示例编写查询以提取数据,请将其放到with子句中,其余的都可以。我看到你正在对数据执行select操作。将有更多的数据,我真的只知道列名。有没有办法在没有指定数据的情况下选择cust_id、cust_name、prod_id?with the_data AS()只是我在内存中构建临时表的一种方法。你只需要像平常一样查询你的表。def与示例数据一起工作,只需一个查询,它确实会有点不对劲,但我确信这只是我正在做的事情。如果你可以按照示例编写查询以提取数据,请将其放到with子句中,其余部分将工作。MTO-这一行做什么?创建或替换类型VARCHAR2s_表作为VARCHAR2(4000)的表/创建一个可用于存储的(类似于其他语言中的数组),在本例中,该数组可用于执行字符串聚合。因此,它是一个临时/永久表,用于存储函数中使用的数据?不,在本例中,它不是一个表;它是一种内存(数组)结构,可用于SQL和PL/SQL过程和函数中。但是,它可以用作表中某列的数据类型(请参阅)或.MTO-这一行的作用是什么?创建或替换类型VARCHAR2s_表作为VARCHAR2(4000)的表/创建一个可用于存储的(类似于其他语言中的数组),在本例中,该数组可用于执行字符串聚合。因此,它是一个临时/永久表,用于存储函数中使用的数据?不,在本例中,它不是一个表;它是一种内存(数组)结构,可用于SQL和PL/SQL过程和函数中。但是,它可以用作表中某列的数据类型(请参阅),也可以用作。