Oracle LISTAGG 和 Coalesce
Oracle LISTAGG and Coalesce
我已经浓缩了以下 table EPS_PROPOSAL_EXT_T
:
+--------------------+------------+------------+
| PROPOSAL_NUMBER |ONR_OPTION_1|ONR_Option_2| ...
+--------------------+------------+------------+
| 1234 | N | N | ...
| 1235 | Y | Y | ...
| 1236 | N | Y | ...
+--------------------+------------+------------+
这里的问题是我需要对所有这些不同的 ONR_Options 执行 LISTAGG
,但我不能让它们显示为 'Y'
。我需要用人类可以理解的东西替换 'Y'
的那些。请参阅下面我尝试执行此操作的 SELECT
声明:
SELECT eps.PROPOSAL_NUMBER, eps.TITLE, per.FULL_NAME, ext.NRP_IREF_CD, ext.RESEARCH_TYPE_CD,
nsf.NSF_CODE, ext.NPS_THRUST_DESCRIPTION,
CASE
WHEN ext.ONR_Option_1 = 'Y' THEN 'Option 1'
WHEN ext.ONR_Option_2 = 'Y' THEN 'Option 2'
WHEN ext.ONR_Option_3 = 'Y' THEN 'Option 3'
WHEN ext.ONR_Option_4 = 'Y' THEN 'Option 4'
WHEN ext.ONR_Option_5 = 'Y' THEN 'Option 5'
WHEN ext.ONR_Option_6 = 'Y' THEN 'Option 6'
WHEN ext.ONR_Option_7 = 'Y' THEN 'Option 7'
WHEN ext.ONR_Option_8 = 'Y' THEN 'Option 8'
WHEN ext.ONR_Option_9 = 'Y' THEN 'Option 9'
WHEN ext.ONR_NOT_APPLICABLE = 'Y' THEN 'Not Applicable'
ELSE ''
END ONR
FROM EPS_PROPOSAL eps
LEFT JOIN EPS_PROPOSAL_EXT_T ext
ON eps.PROPOSAL_NUMBER = ext.PROPOSAL_NUMBER
LEFT JOIN EPS_PROP_PERSON per
ON eps.PROPOSAL_NUMBER = per.PROPOSAL_NUMBER AND
(per.PROP_PERSON_ROLE_ID = 'PI' OR per.PROP_PERSON_ROLE_ID = 'PD')
LEFT JOIN EPS_PROP_ABSTRACT abs
ON eps.PROPOSAL_NUMBER = abs.PROPOSAL_NUMBER
LEFT JOIN NSF_CODES nsf
ON eps.NSF_CODE = nsf.NSF_SEQUENCE_NUMBER
WHERE eps.OWNED_BY_UNIT = '401' AND eps.requested_start_date_initial >= DATE '2019-10-01';
这可行,但您可以看到它的问题,对吗?我设置 CASE
语句的方式不会考虑特定 PROPOSAL_NUMBER 有多个 ONR_Option 即 TRUE
.
在我上面给出的示例中,如果我搜索编号为 1235 的提案; ONR
结果应该是 - 'Option 1, Option 2'.
如何解决 LISTAGG
和 COALESCE
的这个难题?或者这是解决这个问题的方法?
LISTAGG
在这里没有帮助。为什么?因为你的数据模型错误。在我看来,应该是这样的:
SQL> with test (prop, onr, status) as
2 (select 1234, '1', 'N' from dual union all
3 select 1234, '2', 'N' from dual union all
4 select 1234, '3', 'Y' from dual union all
5 select 1235, '1', 'Y' from dual union all
6 select 1235, '2', 'Y' from dual union all
7 select 1235, '3', 'N' from dual
8 )
9 select prop,
10 listagg(case when status = 'Y' then 'Option ' || onr end, ',')
11 within group (order by onr) as result
12 from test
13 group by prop;
PROP RESULT
---------- ------------------------------
1234 Option 3
1235 Option 1,Option 2
SQL>
目前的情况,看看这是否 - CASE
的连接数与 table 中的 ONR_OPTION
列一样多,它可以像山羊一样缩放喜欢教飞行,以及删除多个逗号的痛苦 - 帮助:
SQL> with test (prop, onr_1, onr_2, onr_3) as
2 (select 1234, 'N', 'N', 'Y' from dual union all
3 select 1235, 'Y', 'Y', 'N' from dual
4 )
5 select prop,
6 trim(both ',' from
7 case when onr_1 = 'Y' then 'Option 1' else null end ||','||
8 case when onr_2 = 'Y' then 'Option 2' else null end ||','||
9 case when onr_3 = 'Y' then 'Option 3' else null end
10 ) as result
11 from test;
PROP RESULT
---------- ------------------------------
1234 Option 3
1235 Option 1,Option 2
SQL>
我已经浓缩了以下 table EPS_PROPOSAL_EXT_T
:
+--------------------+------------+------------+
| PROPOSAL_NUMBER |ONR_OPTION_1|ONR_Option_2| ...
+--------------------+------------+------------+
| 1234 | N | N | ...
| 1235 | Y | Y | ...
| 1236 | N | Y | ...
+--------------------+------------+------------+
这里的问题是我需要对所有这些不同的 ONR_Options 执行 LISTAGG
,但我不能让它们显示为 'Y'
。我需要用人类可以理解的东西替换 'Y'
的那些。请参阅下面我尝试执行此操作的 SELECT
声明:
SELECT eps.PROPOSAL_NUMBER, eps.TITLE, per.FULL_NAME, ext.NRP_IREF_CD, ext.RESEARCH_TYPE_CD,
nsf.NSF_CODE, ext.NPS_THRUST_DESCRIPTION,
CASE
WHEN ext.ONR_Option_1 = 'Y' THEN 'Option 1'
WHEN ext.ONR_Option_2 = 'Y' THEN 'Option 2'
WHEN ext.ONR_Option_3 = 'Y' THEN 'Option 3'
WHEN ext.ONR_Option_4 = 'Y' THEN 'Option 4'
WHEN ext.ONR_Option_5 = 'Y' THEN 'Option 5'
WHEN ext.ONR_Option_6 = 'Y' THEN 'Option 6'
WHEN ext.ONR_Option_7 = 'Y' THEN 'Option 7'
WHEN ext.ONR_Option_8 = 'Y' THEN 'Option 8'
WHEN ext.ONR_Option_9 = 'Y' THEN 'Option 9'
WHEN ext.ONR_NOT_APPLICABLE = 'Y' THEN 'Not Applicable'
ELSE ''
END ONR
FROM EPS_PROPOSAL eps
LEFT JOIN EPS_PROPOSAL_EXT_T ext
ON eps.PROPOSAL_NUMBER = ext.PROPOSAL_NUMBER
LEFT JOIN EPS_PROP_PERSON per
ON eps.PROPOSAL_NUMBER = per.PROPOSAL_NUMBER AND
(per.PROP_PERSON_ROLE_ID = 'PI' OR per.PROP_PERSON_ROLE_ID = 'PD')
LEFT JOIN EPS_PROP_ABSTRACT abs
ON eps.PROPOSAL_NUMBER = abs.PROPOSAL_NUMBER
LEFT JOIN NSF_CODES nsf
ON eps.NSF_CODE = nsf.NSF_SEQUENCE_NUMBER
WHERE eps.OWNED_BY_UNIT = '401' AND eps.requested_start_date_initial >= DATE '2019-10-01';
这可行,但您可以看到它的问题,对吗?我设置 CASE
语句的方式不会考虑特定 PROPOSAL_NUMBER 有多个 ONR_Option 即 TRUE
.
在我上面给出的示例中,如果我搜索编号为 1235 的提案; ONR
结果应该是 - 'Option 1, Option 2'.
如何解决 LISTAGG
和 COALESCE
的这个难题?或者这是解决这个问题的方法?
LISTAGG
在这里没有帮助。为什么?因为你的数据模型错误。在我看来,应该是这样的:
SQL> with test (prop, onr, status) as
2 (select 1234, '1', 'N' from dual union all
3 select 1234, '2', 'N' from dual union all
4 select 1234, '3', 'Y' from dual union all
5 select 1235, '1', 'Y' from dual union all
6 select 1235, '2', 'Y' from dual union all
7 select 1235, '3', 'N' from dual
8 )
9 select prop,
10 listagg(case when status = 'Y' then 'Option ' || onr end, ',')
11 within group (order by onr) as result
12 from test
13 group by prop;
PROP RESULT
---------- ------------------------------
1234 Option 3
1235 Option 1,Option 2
SQL>
目前的情况,看看这是否 - CASE
的连接数与 table 中的 ONR_OPTION
列一样多,它可以像山羊一样缩放喜欢教飞行,以及删除多个逗号的痛苦 - 帮助:
SQL> with test (prop, onr_1, onr_2, onr_3) as
2 (select 1234, 'N', 'N', 'Y' from dual union all
3 select 1235, 'Y', 'Y', 'N' from dual
4 )
5 select prop,
6 trim(both ',' from
7 case when onr_1 = 'Y' then 'Option 1' else null end ||','||
8 case when onr_2 = 'Y' then 'Option 2' else null end ||','||
9 case when onr_3 = 'Y' then 'Option 3' else null end
10 ) as result
11 from test;
PROP RESULT
---------- ------------------------------
1234 Option 3
1235 Option 1,Option 2
SQL>