ORACLE/SQL:wm_concat和order by

ORACLE/SQL:wm_concat和order by,sql,oracle,oracle11g,wm-concat,Sql,Oracle,Oracle11g,Wm Concat,我使用的是oracle 11,不确定确切的版本,但由于Listag不起作用,我想它不是通过ODBC和crystal reports 2008发布的第2版 我的问题是: 这是一张桌子: TABLE ODB.TASK_CARD_CONTROL ------------------------------------------ task_card control_category code -----------------------------------------

我使用的是oracle 11,不确定确切的版本,但由于Listag不起作用,我想它不是通过ODBC和crystal reports 2008发布的第2版

我的问题是:

这是一张桌子:

TABLE ODB.TASK_CARD_CONTROL  
------------------------------------------  
task_card     control_category     code  
------------------------------------------  
1                  zone             17  
1                  zone             33  
1                  zone             21  
2                  zone             18  
2                  zone             05  
3                  zone             55  
3                  zone             32  
3                  zone             72 
我使用WM_CONCAT函数来获得如下结果:

task_card      zones
1              17,33,21
2              18,05
3              55,32,72
以下是用于此目的的SQL:

SELECT TASK_CARD, WM_CONCAT(code) as ZONES
FROM ODB.TASK_CARD_CONTROL
WHERE ODB.TASK_CARD_CONTROL.CONTROL_CATEGORY = 'ZONE'
GROUP BY TASK_CARD
但我想对区域进行排序,所以我尝试了以下方法:

SELECT TASK_CARD, WM_CONCAT(code) as ZONES
FROM (SELECT TASK_CARD, CODE, CONTROL_CATEGORY FROM ODB.TASK_CARD_CONTROL 
ORDER BY CODE)
WHERE ODB.TASK_CARD_CONTROL.CONTROL_CATEGORY = 'ZONE'
GROUP BY TASK_CARD
但由于某些原因,它返回以下错误:

Failed to retrieve data from the database.
Details: 42S22:[Oracle][ODBC][Ora]ORA-00904: 
"ODB"."TASK_CARD_CONTROL"."CONTROL_CATEGORY" : invalid identifier

我真的不明白我做错了什么。。。有人能给我一个提示吗?

您不能从内部查询之外引用ODB.TASK\u CARD\u CONTROL.CONTROL\u类别。尝试:

SELECT TASK_CARD, WM_CONCAT(code) as ZONES
FROM (SELECT TASK_CARD, CODE, CONTROL_CATEGORY FROM ODB.TASK_CARD_CONTROL 
      WHERE ODB.TASK_CARD_CONTROL.CONTROL_CATEGORY = 'ZONE'
      ORDER BY CODE)
GROUP BY TASK_CARD

使用ListAgg而不是wm_concat

SELECT TASK_CARD, ListAgg(code) within (order by code asc) as ZONES

如果在from子句中为子查询指定名称,则可以引用子查询本身中的列

SELECT t1.TASK_CARD
, WM_CONCAT(t1.code) as ZONES
FROM 
(SELECT TASK_CARD, CODE, CONTROL_CATEGORY FROM ODB.TASK_CARD_CONTROL ORDER BY CODE) t1
WHERE t1.CONTROL_CATEGORY = 'ZONE'
GROUP BY t1.TASK_CARD

对于仍在使用wm_CONCAT a.k.a.旧db版本的任何人: 解决方案是添加不同的条件,然后还将对连接的值应用升序

不要问为什么它没有文档化,但它会起作用

此外,在子查询中使用orderby,在wm_concat之前,只会随机化顺序,因此不建议使用它

请求的SQL的示例:

SELECT TASK_CARD, WM_CONCAT(distinct code) as ZONES
FROM ODB.TASK_CARD_CONTROL
WHERE ODB.TASK_CARD_CONTROL.CONTROL_CATEGORY = 'ZONE'
GROUP BY TASK_CARD;
请注意,distinct选项在过程/包中使用时不起作用

按所需列排序,然后 外部查询中的订单按行号排序。 使用该函数。 此函数具有最后一个rownum顺序的逻辑:

Select wmsys.wm_concat(t) CONCAT from 
(
    Select t from (
        Select t from (
            Select 'aa' t from dual
            union
            Select 'zz' t from dual
            union
            Select 'pp' t from dual
            union
            Select 'll' t from dual
            union
            Select 'mm' t from dual
            union
            Select 'xx' t from dual
            union
            Select 'cc' t from dual
        ) a 
        order by t
    ) order by rownum
) t
Listag是在11g版本2中引入的

因此,在不支持Listag的11g之前的Oracle版本中,可以使用ROW\ U NUMBER和SYS\ U CONNECT\ U BY\ U PATH函数

切勿使用WM_CONCAT,因为它是一个未记录的功能,并且已从12c版本中删除

任何依赖wm_concat功能的应用程序一旦升级到12c将无法工作。从那以后,它就被移除了。看

您将收到一个“无效标识符”错误:

SQL> SELECT banner FROM v$version;

BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE    12.1.0.1.0      Production
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production

SQL> SELECT deptno, wm_concat(ename) FROM emp;
SELECT deptno, wm_concat(ename) FROM emp
               *
ERROR at line 1:
ORA-00904: "WM_CONCAT": invalid identifier

因此,依赖最新版本中不再提供的未记录功能是没有意义的。

我同时也考虑过这一点;我试过这样做:从SELECT TASK_CARD,CODE,FROM ODB.TASK_CARD_CONTROL,其中ODB.TASK_CARD_CONTROL.CONTROL_CATEGORY='ZONE'ORDER BY CODE GROUP BY TASK_CARD,但是SELECT中省略了CONTROL_CATEGORY给了我一个错误。将它添加回您的查询中,现在似乎工作正常!谢谢:@LalitKumarB你为什么问我?我是在回答一个问题,WM_CONCAT被偶然使用,而不是提倡使用它@LalitKumarB没问题!即使没有子查询别名,您也可以这样做,因为已接受的答案显示OP明确声明他不能使用listagg。而且,它是在集团内部。
SQL> select banner from v$version where rownum = 1;

BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production

SQL> SELECT object_name
  2  FROM dba_objects
  3  WHERE owner='WMSYS'
  4  AND object_name LIKE 'WM\_%' ESCAPE '\';

OBJECT_NAME
----------------------------------------------------------------------------
WM_REPLICATION_INFO
WM_RDIFF
WM_PERIOD
WM_PERIOD
WM_OVERLAPS
WM_MEETS
WM_LESSTHAN
WM_LDIFF
WM_INTERSECTION
WM_INSTALLATION
WM_GREATERTHAN
WM_EVENTS_INFO
WM_ERROR
WM_ERROR
WM_EQUALS
WM_DDL_UTIL
WM_DDL_UTIL
WM_CONTAINS
WM_COMPRESS_BATCH_SIZES
WM_COMPRESSIBLE_TABLES

20 rows selected.

SQL>
SQL> SELECT banner FROM v$version;

BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE    12.1.0.1.0      Production
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production

SQL> SELECT deptno, wm_concat(ename) FROM emp;
SELECT deptno, wm_concat(ename) FROM emp
               *
ERROR at line 1:
ORA-00904: "WM_CONCAT": invalid identifier