oracle 与管道字符连接,但删除尾随管道(仅限表达式)

exdqitrt  于 2023-11-17  发布在  Oracle
关注(0)|答案(2)|浏览(150)

具体地说,我使用的是REGEXP_REPLACE,如果我使用逗号,它会很好地工作。|),下面的代码不会删除任何尾随管道。知道为什么吗?
使用逗号的代码:

select username,
  regexp_replace (
   (case when clan is not null then clan ||', ' END) ||
   (case when job is not null then job ||', ' END) ||       
   (case when level is not null then level END), ', $',' ') desc      
 from dominions;

字符串
使用逗号校正输出:

USERNAME       DESC
 benedict       rage, hunter, 89
 jamilah        wizard, 42
 anne           happy_elfs, elven
 tommy          19


使用管道编码:

select username,
  regexp_replace (
   (case when clan is not null then clan ||' | ' END) ||
   (case when job is not null then job ||' | ' END) ||       
   (case when level is not null then level END), '| $',' ') desc      
 from dominions;


使用管道的错误输出:

USERNAME       DESC
 benedict       rage | hunter | 89 |
 jamilah        wizard | 42 |
 anne           happy_elfs | elven |
 tommy          19 |


如果上述代码不能被纠正,任何其他解决方案使用表达式?

esyap4oy

esyap4oy1#

LEVELDESC都是保留字;您不能将它们用作不带引号的标识符,而必须使用带引号的标识符(您可能应该使用不同的标识符,而不是使用带引号的标识符)。
|在正则表达式中有特殊的含义,如OR。如果你想使用它作为字符,那么你需要使用\|来转义它:

SELECT username,
       REGEXP_REPLACE(
         CASE WHEN clan    IS NOT NULL THEN clan ||' | ' END ||
         CASE WHEN job     IS NOT NULL THEN job ||' | ' END ||       
         CASE WHEN "LEVEL" IS NOT NULL THEN "LEVEL" END,
         ' \| $'
       ) AS description
FROM   dominions;

字符串
其中,对于样本数据:

CREATE TABLE dominions (username, clan, job, "LEVEL") AS
 SELECT 'benedict', 'rage',       'hunter', 89   FROM DUAL UNION ALL
 SELECT 'jamilah',  NULL,         'wizard', 42   FROM DUAL UNION ALL
 SELECT 'anne',     'happy_elfs', 'elven',  NULL FROM DUAL UNION ALL
 SELECT 'tommy',    NULL,         NULL,     19   FROM DUAL;


产出:
| 用户名|描述|
| --|--|
| 本笃|愤怒|猎人|89|
| 贾米拉|wizard巫师|42|
| 安妮|快乐的|精灵|
| 汤米| 19 |
正则表达式是缓慢的,它可能需要更多的类型,但你可以使用简单的字符串函数代替:

SELECT username,
       REPLACE(
         TRIM(
           TRAILING '|' FROM
           CASE WHEN clan    IS NOT NULL THEN clan ||'|' END ||
           CASE WHEN job     IS NOT NULL THEN job ||'|' END ||       
           CASE WHEN "LEVEL" IS NOT NULL THEN "LEVEL" END
         ),
         '|',
         ' | '
       ) AS description
FROM   dominions;


或者生成字符串,这样就不必删除尾随分隔符:

SELECT username,
       CASE
       WHEN clan IS NOT NULL
       THEN clan || CASE WHEN job IS NOT NULL OR "LEVEL" IS NOT NULL THEN ' | ' END
       END
       ||
       CASE
       WHEN job IS NOT NULL
       THEN job || CASE WHEN "LEVEL" IS NOT NULL THEN ' | ' END
       END
       ||
       CASE WHEN "LEVEL" IS NOT NULL THEN "LEVEL" END
         AS description
FROM   dominions;


这两个查询的输出与第一个查询相同。
fiddle

zzlelutf

zzlelutf2#

如果你使用的是php之类的代码,你可能会检查最后一个元素,但如果你纯粹是在SQL中执行这个操作,我建议你在最后一个命令的末尾添加一个null值或空字符串,以避免任何错误。请注意,这是一个理论上的解决方案,因为我不知道你使用的是哪个SQL版本,如果你将它与其他编程语言结合使用,你可以使用if/then来检测序列中的最后一项。我相信最终会有人对此有更好的答案。

相关问题