PLSQL 10g - 创建一个字符串列表
PLSQL 10g- create a list of strings
我研究这个有一段时间了。我在下面有一个数据集,我需要将所需的输出放在字符串列表中。如果有重复的产品,我希望它单独一行。下面得到的是一行中的所有客户 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 函数,但请注意 return 数据类型是 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
如果您无法访问它(它不是受支持的功能,也不总是安装),那么您可以实施 Tom Kyte's STRAGG user-defined analytic as shown here
除此之外,您最终可以选择 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
函数(并非在所有系统上都可用,并且是 not available at all on Oracle 12c),您可以使用集合和 COLLECT
聚合函数来实现.
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;
/
查询
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;
输出:
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
我研究这个有一段时间了。我在下面有一个数据集,我需要将所需的输出放在字符串列表中。如果有重复的产品,我希望它单独一行。下面得到的是一行中的所有客户 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 函数,但请注意 return 数据类型是 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
如果您无法访问它(它不是受支持的功能,也不总是安装),那么您可以实施 Tom Kyte's STRAGG user-defined analytic as shown here
除此之外,您最终可以选择 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
函数(并非在所有系统上都可用,并且是 not available at all on Oracle 12c),您可以使用集合和 COLLECT
聚合函数来实现.
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;
/
查询
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;
输出:
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