我最近开始了我的SQL冒险。我被要求写查询,将标题放在人名之后。标题是名称记录的一部分。所以,如果有人的姓氏是“约翰逊”,那么。我需要制作约翰逊(德)'出来的。我只需要选择包含两个单词的名称(标题为)。我找到了解决这个问题的正确方法,这里是查询:
SELECT SUBSTR(naam, INSTR(naam,' ')+1) || ' (' || LOWER(SUBSTR(naam, 1, INSTR(naam, ' ') -1)) || ')'
FROM medewerkers
WHERE naam like '% %';
现在是我的问题,是否有可能使其更加冗长?我真的更喜欢用CONCAT代替||我不明白将SQL的冗长与sings混合的概念。我知道这个查询没有任何意义,因为SQL不是用来格式化输出的,而是我在学校里做的事情(他们甚至不能像SQL一样简单地教它)。
答案 0 :(得分:2)
我建议找到一个解决方案,而不是将其转换为等效的CONCAT
表达式:
where
子句并在结果集中包含所有名称。对于此任务,正则表达式派上用场:
select regexp_replace(trim(naam), '^(\S+(\s+[^A-Z]\S*)*)\s+(\S.*)$', '\3 (\1)')
from medewerkers
该函数的最后一个参数在显示匹配时生成的格式时非常易读。
注意:根据语言设置(即NLS_SORT,不区分大小写排序),可能需要向preg_replace
添加更多参数以强制区分大小写:
select regexp_replace(trim(naam), '^(\S+(\s+[^A-Z]\S*)*)\s+(\S.*)$', '\3 (\1)', 1, 0, 'c')
from medewerkers
以下是一些测试用例:
select id, naam,
regexp_replace(trim(naam), '^(\S+(\s+[^A-Z]\S*)*)\s+(\S.*)$', '\3 (\1)')
as corrected
from (select 1 id, 'De Ridder' as naam from dual union
select 2, ' de Meester' from dual union
select 3, 'Smits' from dual union
select 4, 'Vandenborre ' from dual union
select 5, 'Van den Borre' from dual union
select 6, ' van der Meulen' from dual union
select 7, 'van ''t Oosten' from dual union
select 8, 'Van de Walle-Van der Meulen' from dual)
order by id;
输出:
id | naam | corrected
---+-----------------------------+------------------
1 | De Ridder | Ridder (De)
2 | de Meester | Meester (de)
3 | Smits | Smits
4 | Vandenborre | Vandenborre
5 | Van den Borre | Borre (Van den)
6 | van der Meulen | Meulen (van der)
7 | van 't Oosten | Oosten (van 't)
8 | Van de Walle-Van der Meulen | Walle-Van der Meulen (Van de)