ORACLE SQL LISTAGG 未返回预期结果
ORACLE SQL LISTAGG not returning expected result
我是 运行 Oracle Database 11g Enterprise 11.2.0.4.0,PL/SQL 11.2.0.4.0 版,我在获取 LISTAGG 函数到 return 时遇到了一些问题我期待的数据集。
场景如下:
我有一个看起来像这样的数据集
我想 return 一行的一列中的 MOD_CODE 列中的值,例如:
AR4001,AR4002
我一直在尝试使用 LISTAGG 函数完成此操作,例如:
SELECT LISTAGG(MOD_CODE,',') WITHIN GROUP (ORDER BY MOD_CODE)
FROM XOTEST_A
WHERE MOD_CODE IN ('AR4001','AR4002')
但它没有 returning 任何数据(见屏幕截图)
我做错了什么?这是更广泛场景的一部分,所以我理想情况下想使用 LISTAGG 或类似的(我尝试使用 wm_concat 函数,但它的 returning HUGECLOB 数据类型也不起作用)
我已经编写了SQL来构建重现场景
-- CREATE TABLE
CREATE TABLE XOTEST_A (
MOD_CODE NVARCHAR2(12),
DOM_CODE NVARCHAR2(12),
MOD_SNAM NVARCHAR2(15),
MOD_NAME NVARCHAR2(120),
SCH_CODE NVARCHAR2(6),
LEV_CODE NVARCHAR2(6),
PRS_CODE NVARCHAR2(12),
MOT_CODE NVARCHAR2(6),
MOD_CRDT NUMBER(5,2),
MOD_HOURS NUMBER(4),
MAP_CODE NVARCHAR2(12),
MOD_EREF NVARCHAR2(12),
MKS_CODE NVARCHAR2(6),
FPT_CODE NVARCHAR2(12),
ESB_CODE NVARCHAR2(6),
MOD_NPER NUMBER(2),
MOD_MOAS NVARCHAR2(1),
MOD_PMOA NVARCHAR2(1),
MEP_CODE NVARCHAR2(6),
DPT_CODE NVARCHAR2(12),
ELV_CODE NVARCHAR2(3),
ECL_CODE NVARCHAR2(3),
MOD_UTYC NVARCHAR2(3),
MOD_COGC NVARCHAR2(6),
MOD_STAT VARCHAR2(1 BYTE),
MOD_UPDD DATE,
MOD_KEYW NVARCHAR2(100),
MOD_IUSE VARCHAR2(1 BYTE),
MOD_TOCC NVARCHAR2(12),
MOD_DVNC NVARCHAR2(12),
MOD_UDF1 NVARCHAR2(15),
MOD_UDF2 NVARCHAR2(15),
MOD_UDF3 NVARCHAR2(15),
MOD_UDF4 NVARCHAR2(15),
MOD_UDF5 NVARCHAR2(15),
MOD_UDF6 NVARCHAR2(15),
MOD_UDF7 NVARCHAR2(15),
MOD_UDF8 NVARCHAR2(15),
MOD_UDF9 NVARCHAR2(15),
MOD_UDFA NVARCHAR2(15),
MOD_UDFB NVARCHAR2(15),
MOD_UDFC NVARCHAR2(15),
MOD_UDFD NVARCHAR2(15),
MOD_UDFE NVARCHAR2(15),
MOD_UDFF NVARCHAR2(15),
MOD_UDFG NVARCHAR2(15),
MOD_UDFH NVARCHAR2(15),
MOD_UDFI NVARCHAR2(15),
MOD_UDFJ NVARCHAR2(100),
MOD_UDFK NVARCHAR2(100),
MOD_VALC NVARCHAR2(12),
MOD_APRT NUMBER(5,2),
MOD_LANG NVARCHAR2(1),
MOD_ERFM NVARCHAR2(1),
MOD_MUSE VARCHAR2(1 BYTE),
MOD_FACC NVARCHAR2(6),
MOD_ISGX VARCHAR2(1 BYTE),
MOD_REGM NVARCHAR2(1),
MOD_FRID VARCHAR2(1 BYTE),
MOD_WEEI NVARCHAR2(1),
MOD_MODE NVARCHAR2(1)--,
--MOD_NOTE NCLOB
)
--INSERT VALUES INTO THE TABLE
INSERT INTO XOTEST_A (MOD_CODE,DOM_CODE,MOD_SNAM,MOD_NAME,SCH_CODE,LEV_CODE,PRS_CODE,MOT_CODE,MOD_CRDT,MOD_HOURS,MAP_CODE,MOD_EREF,MKS_CODE,FPT_CODE,ESB_CODE,MOD_NPER,MOD_MOAS,MOD_PMOA,MEP_CODE,DPT_CODE,ELV_CODE,ECL_CODE,MOD_UTYC,MOD_COGC,MOD_STAT,MOD_UPDD,MOD_KEYW,MOD_IUSE,MOD_TOCC,MOD_DVNC,MOD_UDF1,MOD_UDF2,MOD_UDF3,MOD_UDF4,MOD_UDF5,MOD_UDF6,MOD_UDF7,MOD_UDF8,MOD_UDF9,MOD_UDFA,MOD_UDFB,MOD_UDFC,MOD_UDFD,MOD_UDFE,MOD_UDFF,MOD_UDFG,MOD_UDFH,MOD_UDFI,MOD_UDFJ,MOD_UDFK,MOD_VALC,MOD_APRT,MOD_LANG,MOD_ERFM,MOD_MUSE,MOD_FACC,MOD_ISGX,MOD_REGM,MOD_FRID,MOD_WEEI,MOD_MODE/*,MOD_NOTE*/)
VALUES ('AR4001', 'SEN', 'AR4001', 'DESIGN STUDIO 1A', 'UL', '1', 'HASGRA1', 'A', 15, NULL, 'AR4001', NULL, 'AMOD', NULL, NULL, 1, 'M', 'M', NULL, 'SENDES', NULL, NULL, 'F', NULL, NULL, NULL, NULL, 'Y', NULL, NULL, NULL, '15/05/2008', 'V', 'P', NULL, 'N', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'N', NULL, NULL, NULL, NULL, NULL, NULL/*, ''*/)
COMMIT;
INSERT INTO XOTEST_A (MOD_CODE,DOM_CODE,MOD_SNAM,MOD_NAME,SCH_CODE,LEV_CODE,PRS_CODE,MOT_CODE,MOD_CRDT,MOD_HOURS,MAP_CODE,MOD_EREF,MKS_CODE,FPT_CODE,ESB_CODE,MOD_NPER,MOD_MOAS,MOD_PMOA,MEP_CODE,DPT_CODE,ELV_CODE,ECL_CODE,MOD_UTYC,MOD_COGC,MOD_STAT,MOD_UPDD,MOD_KEYW,MOD_IUSE,MOD_TOCC,MOD_DVNC,MOD_UDF1,MOD_UDF2,MOD_UDF3,MOD_UDF4,MOD_UDF5,MOD_UDF6,MOD_UDF7,MOD_UDF8,MOD_UDF9,MOD_UDFA,MOD_UDFB,MOD_UDFC,MOD_UDFD,MOD_UDFE,MOD_UDFF,MOD_UDFG,MOD_UDFH,MOD_UDFI,MOD_UDFJ,MOD_UDFK,MOD_VALC,MOD_APRT,MOD_LANG,MOD_ERFM,MOD_MUSE,MOD_FACC,MOD_ISGX,MOD_REGM,MOD_FRID,MOD_WEEI,MOD_MODE/*,MOD_NOTE*/)
VALUES ('AR4002', 'SEN', 'AR4002', 'DESIGN STUDIO 1A', 'UL', '1', 'HASGRA1', 'A', 15, NULL, 'AR4002', NULL, 'AMOD', NULL, NULL, 1, 'M', 'M', NULL, 'SENDES', NULL, NULL, 'F', NULL, NULL, NULL, NULL, 'Y', NULL, NULL, NULL, '15/05/2008', 'V', 'P', NULL, 'N', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'N', NULL, NULL, NULL, NULL, NULL, NULL/*, ''*/)
COMMIT;
-- NOW RUN THE SELECT STATEMENT
SELECT LISTAGG(MOD_CODE,',') WITHIN GROUP (ORDER BY MOD_CODE) LISTAGG_OUTPUT
FROM XOTEST_A
WHERE MOD_CODE IN ('AR4001','AR4002')
But it is not returning any data (see screenshot)
您的样本数据产生了预期的结果。 here is a SQL Fiddle。所以问题不在于语法或数据库。剩下数据了。
最可能的解释是您的 MOD_CODE 值与 WHERE 子句中的值不匹配。很难从屏幕截图中看出,但如果您的数据具有不可见的值,例如尾随空格 ('AR4001 '
、'AR4002 '
),那么您的 WHERE 子句将 return 没有行。
有几种方法可以对此进行测试。 运行 您的查询没有 WHERE 子句。测试您的数据长度 - vsize(mod_code)
- 或转储内容 - dump(mod_code)
.
这似乎与错误 19461687 和 有关。如果您从 11gR2 或 12cR1 中的查询转储聚合值,您会看到:
LISTAGG_OUTPUT
--------------------------------------------------------------------------------------------------
Typ=1 Len=25 CharacterSet=AL32UTF8: 0,41,0,52,0,34,0,30,0,30,0,31,2c,0,41,0,52,0,34,0,30,0,30,0,32
在SQL*Plus和SQL开发者中实际值显示为:
LISTAGG_OUTPUT
----------------------------------------
A R 4 0 0 1, A R 4 0 0 2
而且您无法从 SQL 开发人员那里复制值。 (在12cR2中,转储中不再出现零,显示的值没有空格,你可以复制它,所以这个bug似乎已经修复了。)
这些空字节似乎导致 Toad 根本不显示该值,大概是因为它看到第一个空字节并将其视为字符串终止符(或无论如何)。
SQL Fiddle 似乎可以解决这个问题,但是 db<>fiddle 似乎也有问题,并且 return 没有任何问题存在该查询时的整个 fiddle。
您可以将 table 列重新定义为 varchar2
而不是 nvarchar2
,但出于某种原因我假设它是该数据类型,因此这可能不切实际。
因此您可以将其转换为查询的一部分:
SELECT LISTAGG(CAST(MOD_CODE AS VARCHAR2(12)),',')
WITHIN GROUP (ORDER BY MOD_CODE) LISTAGG_OUTPUT
FROM XOTEST_A
WHERE MOD_CODE IN ('AR4001','AR4002');
LISTAGG_OUTPUT
----------------------------------------
AR4001,AR4002
或者查看 bug 19461687 的补丁是否为您解决了问题。
我是 运行 Oracle Database 11g Enterprise 11.2.0.4.0,PL/SQL 11.2.0.4.0 版,我在获取 LISTAGG 函数到 return 时遇到了一些问题我期待的数据集。
场景如下:
我有一个看起来像这样的数据集
我想 return 一行的一列中的 MOD_CODE 列中的值,例如:
AR4001,AR4002
我一直在尝试使用 LISTAGG 函数完成此操作,例如:
SELECT LISTAGG(MOD_CODE,',') WITHIN GROUP (ORDER BY MOD_CODE)
FROM XOTEST_A
WHERE MOD_CODE IN ('AR4001','AR4002')
但它没有 returning 任何数据(见屏幕截图)
我做错了什么?这是更广泛场景的一部分,所以我理想情况下想使用 LISTAGG 或类似的(我尝试使用 wm_concat 函数,但它的 returning HUGECLOB 数据类型也不起作用)
我已经编写了SQL来构建重现场景
-- CREATE TABLE
CREATE TABLE XOTEST_A (
MOD_CODE NVARCHAR2(12),
DOM_CODE NVARCHAR2(12),
MOD_SNAM NVARCHAR2(15),
MOD_NAME NVARCHAR2(120),
SCH_CODE NVARCHAR2(6),
LEV_CODE NVARCHAR2(6),
PRS_CODE NVARCHAR2(12),
MOT_CODE NVARCHAR2(6),
MOD_CRDT NUMBER(5,2),
MOD_HOURS NUMBER(4),
MAP_CODE NVARCHAR2(12),
MOD_EREF NVARCHAR2(12),
MKS_CODE NVARCHAR2(6),
FPT_CODE NVARCHAR2(12),
ESB_CODE NVARCHAR2(6),
MOD_NPER NUMBER(2),
MOD_MOAS NVARCHAR2(1),
MOD_PMOA NVARCHAR2(1),
MEP_CODE NVARCHAR2(6),
DPT_CODE NVARCHAR2(12),
ELV_CODE NVARCHAR2(3),
ECL_CODE NVARCHAR2(3),
MOD_UTYC NVARCHAR2(3),
MOD_COGC NVARCHAR2(6),
MOD_STAT VARCHAR2(1 BYTE),
MOD_UPDD DATE,
MOD_KEYW NVARCHAR2(100),
MOD_IUSE VARCHAR2(1 BYTE),
MOD_TOCC NVARCHAR2(12),
MOD_DVNC NVARCHAR2(12),
MOD_UDF1 NVARCHAR2(15),
MOD_UDF2 NVARCHAR2(15),
MOD_UDF3 NVARCHAR2(15),
MOD_UDF4 NVARCHAR2(15),
MOD_UDF5 NVARCHAR2(15),
MOD_UDF6 NVARCHAR2(15),
MOD_UDF7 NVARCHAR2(15),
MOD_UDF8 NVARCHAR2(15),
MOD_UDF9 NVARCHAR2(15),
MOD_UDFA NVARCHAR2(15),
MOD_UDFB NVARCHAR2(15),
MOD_UDFC NVARCHAR2(15),
MOD_UDFD NVARCHAR2(15),
MOD_UDFE NVARCHAR2(15),
MOD_UDFF NVARCHAR2(15),
MOD_UDFG NVARCHAR2(15),
MOD_UDFH NVARCHAR2(15),
MOD_UDFI NVARCHAR2(15),
MOD_UDFJ NVARCHAR2(100),
MOD_UDFK NVARCHAR2(100),
MOD_VALC NVARCHAR2(12),
MOD_APRT NUMBER(5,2),
MOD_LANG NVARCHAR2(1),
MOD_ERFM NVARCHAR2(1),
MOD_MUSE VARCHAR2(1 BYTE),
MOD_FACC NVARCHAR2(6),
MOD_ISGX VARCHAR2(1 BYTE),
MOD_REGM NVARCHAR2(1),
MOD_FRID VARCHAR2(1 BYTE),
MOD_WEEI NVARCHAR2(1),
MOD_MODE NVARCHAR2(1)--,
--MOD_NOTE NCLOB
)
--INSERT VALUES INTO THE TABLE
INSERT INTO XOTEST_A (MOD_CODE,DOM_CODE,MOD_SNAM,MOD_NAME,SCH_CODE,LEV_CODE,PRS_CODE,MOT_CODE,MOD_CRDT,MOD_HOURS,MAP_CODE,MOD_EREF,MKS_CODE,FPT_CODE,ESB_CODE,MOD_NPER,MOD_MOAS,MOD_PMOA,MEP_CODE,DPT_CODE,ELV_CODE,ECL_CODE,MOD_UTYC,MOD_COGC,MOD_STAT,MOD_UPDD,MOD_KEYW,MOD_IUSE,MOD_TOCC,MOD_DVNC,MOD_UDF1,MOD_UDF2,MOD_UDF3,MOD_UDF4,MOD_UDF5,MOD_UDF6,MOD_UDF7,MOD_UDF8,MOD_UDF9,MOD_UDFA,MOD_UDFB,MOD_UDFC,MOD_UDFD,MOD_UDFE,MOD_UDFF,MOD_UDFG,MOD_UDFH,MOD_UDFI,MOD_UDFJ,MOD_UDFK,MOD_VALC,MOD_APRT,MOD_LANG,MOD_ERFM,MOD_MUSE,MOD_FACC,MOD_ISGX,MOD_REGM,MOD_FRID,MOD_WEEI,MOD_MODE/*,MOD_NOTE*/)
VALUES ('AR4001', 'SEN', 'AR4001', 'DESIGN STUDIO 1A', 'UL', '1', 'HASGRA1', 'A', 15, NULL, 'AR4001', NULL, 'AMOD', NULL, NULL, 1, 'M', 'M', NULL, 'SENDES', NULL, NULL, 'F', NULL, NULL, NULL, NULL, 'Y', NULL, NULL, NULL, '15/05/2008', 'V', 'P', NULL, 'N', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'N', NULL, NULL, NULL, NULL, NULL, NULL/*, ''*/)
COMMIT;
INSERT INTO XOTEST_A (MOD_CODE,DOM_CODE,MOD_SNAM,MOD_NAME,SCH_CODE,LEV_CODE,PRS_CODE,MOT_CODE,MOD_CRDT,MOD_HOURS,MAP_CODE,MOD_EREF,MKS_CODE,FPT_CODE,ESB_CODE,MOD_NPER,MOD_MOAS,MOD_PMOA,MEP_CODE,DPT_CODE,ELV_CODE,ECL_CODE,MOD_UTYC,MOD_COGC,MOD_STAT,MOD_UPDD,MOD_KEYW,MOD_IUSE,MOD_TOCC,MOD_DVNC,MOD_UDF1,MOD_UDF2,MOD_UDF3,MOD_UDF4,MOD_UDF5,MOD_UDF6,MOD_UDF7,MOD_UDF8,MOD_UDF9,MOD_UDFA,MOD_UDFB,MOD_UDFC,MOD_UDFD,MOD_UDFE,MOD_UDFF,MOD_UDFG,MOD_UDFH,MOD_UDFI,MOD_UDFJ,MOD_UDFK,MOD_VALC,MOD_APRT,MOD_LANG,MOD_ERFM,MOD_MUSE,MOD_FACC,MOD_ISGX,MOD_REGM,MOD_FRID,MOD_WEEI,MOD_MODE/*,MOD_NOTE*/)
VALUES ('AR4002', 'SEN', 'AR4002', 'DESIGN STUDIO 1A', 'UL', '1', 'HASGRA1', 'A', 15, NULL, 'AR4002', NULL, 'AMOD', NULL, NULL, 1, 'M', 'M', NULL, 'SENDES', NULL, NULL, 'F', NULL, NULL, NULL, NULL, 'Y', NULL, NULL, NULL, '15/05/2008', 'V', 'P', NULL, 'N', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'N', NULL, NULL, NULL, NULL, NULL, NULL/*, ''*/)
COMMIT;
-- NOW RUN THE SELECT STATEMENT
SELECT LISTAGG(MOD_CODE,',') WITHIN GROUP (ORDER BY MOD_CODE) LISTAGG_OUTPUT
FROM XOTEST_A
WHERE MOD_CODE IN ('AR4001','AR4002')
But it is not returning any data (see screenshot)
您的样本数据产生了预期的结果。 here is a SQL Fiddle。所以问题不在于语法或数据库。剩下数据了。
最可能的解释是您的 MOD_CODE 值与 WHERE 子句中的值不匹配。很难从屏幕截图中看出,但如果您的数据具有不可见的值,例如尾随空格 ('AR4001 '
、'AR4002 '
),那么您的 WHERE 子句将 return 没有行。
有几种方法可以对此进行测试。 运行 您的查询没有 WHERE 子句。测试您的数据长度 - vsize(mod_code)
- 或转储内容 - dump(mod_code)
.
这似乎与错误 19461687 和
LISTAGG_OUTPUT
--------------------------------------------------------------------------------------------------
Typ=1 Len=25 CharacterSet=AL32UTF8: 0,41,0,52,0,34,0,30,0,30,0,31,2c,0,41,0,52,0,34,0,30,0,30,0,32
在SQL*Plus和SQL开发者中实际值显示为:
LISTAGG_OUTPUT
----------------------------------------
A R 4 0 0 1, A R 4 0 0 2
而且您无法从 SQL 开发人员那里复制值。 (在12cR2中,转储中不再出现零,显示的值没有空格,你可以复制它,所以这个bug似乎已经修复了。)
这些空字节似乎导致 Toad 根本不显示该值,大概是因为它看到第一个空字节并将其视为字符串终止符(或无论如何)。
SQL Fiddle 似乎可以解决这个问题,但是 db<>fiddle 似乎也有问题,并且 return 没有任何问题存在该查询时的整个 fiddle。
您可以将 table 列重新定义为 varchar2
而不是 nvarchar2
,但出于某种原因我假设它是该数据类型,因此这可能不切实际。
因此您可以将其转换为查询的一部分:
SELECT LISTAGG(CAST(MOD_CODE AS VARCHAR2(12)),',')
WITHIN GROUP (ORDER BY MOD_CODE) LISTAGG_OUTPUT
FROM XOTEST_A
WHERE MOD_CODE IN ('AR4001','AR4002');
LISTAGG_OUTPUT
----------------------------------------
AR4001,AR4002
或者查看 bug 19461687 的补丁是否为您解决了问题。