2011-02-11 36 views
3

通过ODBC和Crystal Reports 2008,我正在使用oracle 11(不确定关于确切版本,但由于LISTAGG不起作用,我认为它不是版本2)。ORACLE/SQL:wm_concat&order

这里是我的问题:

这里有一个表:

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 

我真不明白我在做什么错在这里...任何人可以给我一个提示?

回答

2

您不能从内部查询的外部引用ODB.TASK_CARD_CONTROL.CONTROL_CATEGORY。尝试:

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 
+0

好吧,我在此期间想过这件事。我尝试过:SELECT TASK_CARD,WM_CONCAT(code)as ZONES FROM(SELECT TASK_CARD,CODE,FROM ODB.TASK_CARD_CONTROL WHERE ODB.TASK_CARD_CONTROL.CONTROL_CATEGORY ='ZONE'ORDER BY CODE) GROUP BY TASK_CARD - 但省略CONTROL_CATEGORY in选择给了我一个错误。在你的查询中添加它,现在它似乎工作正常!谢谢:) – 2011-02-11 15:19:58

+0

@LalitKumarB你为什么问我?我正在回答一个WM_CONCAT被(偶然)使用的问题,而不是主张它的使用! – 2015-09-11 15:56:46

+0

@LalitKumarB没问题! – 2015-09-11 16:10:23

0

如果要给子查询在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 
4

对于任何仍在使用wm_CONCAT(又名旧数据库版本)的人: 解决方案是添加不同的条件,然后它也将升序应用于连接的值。

不要问为什么它没有记录,但它会工作。

此外,在子查询中使用顺序,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; 

一定要小心,在程序/包时使用不同的选项不起作用。

0
  1. 排序所需的列,然后
  2. 在由行号外部查询订单的订单。
  3. 使用该功能。

这个函数有逻辑的最后的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 
0

LISTAGG11g第2版引入。

因此,在甲骨文之前版本到11g其中LISTAGG不支持,你可以使用ROW_NUMBER()SYS_CONNECT_BY_PATH功能。

Oracle String Aggregation Techniques

SELECT task_card, 
    LTRIM(MAX(SYS_CONNECT_BY_PATH(code,',')) 
    KEEP (DENSE_RANK LAST ORDER BY curr),',') AS zones 
    FROM (SELECT task_card, 
       code, 
       ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY code) AS curr, 
       ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY code) -1 AS prev 
     FROM table_name) 
    GROUP BY task_card 
    CONNECT BY prev = PRIOR curr AND task_card= PRIOR task_card 
START WITH curr = 1; 

注意

切勿使用WM_CONCAT因为它是一个未公开的特性,它已经从12C版本中删除。

已经依赖wm_concat函数的任何应用程序在升级到12c后将不起作用。因为它已被删除。见Why not use WM_CONCAT function in Oracle?

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 

因此,没有一点依靠的无证功能这是没有更多的最新版本提供。