Oracle PL/SQL如何连接一行和另一行中值的第一个字母
Posted
技术标签:
【中文标题】Oracle PL/SQL如何连接一行和另一行中值的第一个字母【英文标题】:Oracle PL/SQL how to join first letter of value in a row and another row 【发布时间】:2019-12-12 17:32:22 【问题描述】:第一次提问,希望题名没有写错。
我有一个包含用户名字和姓氏的表格。我需要以以下方式填充 USER 行:
用户必须以名字的第一个字母,然后是他的全名(全部小写)的形式写入 伊万·霍瓦特 = ihorvat 我需要替换符号 č = c, ć = c, š = s 如果 USER 重复,则必须添加重复次数(不包括 1 个)ihorvat, ihorvat2
+----+------+--------+--------+
| id | user | first | last |
+----+------+--------+--------+
| 1 | | Ivan | Horvat |
| 2 | | Matija | Horvat |
| 3 | | Ivan | Babić |
| 4 | |Tomislav| Jurišić|
| 5 | | Ivan | Horvat |
+----+------+--------+--------+
我知道函数,我可以使用函数 LOWER、REPLACE、SUBSTR 等,但我不知道如何将所有这些组合到一个代码中。
【问题讨论】:
从我的角度来看,你应该分为你提到的3点。第一个是串联,第二个是替换,第三个是找到重复的用户。您的用户列是否接受非唯一值? @zagvir 你能告诉我们一些基本代码吗?现在,您要求我们帮助您完成作业...... 我可以把它分成3个点。第一个是 CONCAT(SUBSTR(first, 1, 1), last) 第二个是 REPLACE(REPLACE(user, č, ć)),š, s)... 我不知道如何做最后一点以及如何将它们组合在单个过程/功能中。我刚开始学习 PL/SQL,我了解函数,但我不知道如何组合它们。在哪个模块以及如何。 【参考方案1】:这是一种选择:
第 1 - 7 行 - 示例数据tuser
CTE(第 8 - 15 行)创建所需的格式(“Ivan Horvat”中的“ihorvat”)并翻译字符
最终的select
使用分析函数为每个val
创建“行号”; case
用于连接该行号,如果它大于1
SQL> with test (id, first, last) as
2 (select 1, 'Ivan' , 'Horvat' from dual union all
3 select 2, 'Matija' , 'Horvat' from dual union all
4 select 3, 'Ivan' , 'Babić' from dual union all
5 select 4, 'Tomislav', 'Jurišić' from dual union all
6 select 5, 'Ivan' , 'Horvat' from dual
7 ),
8 tuser as
9 (select id,
10 translate(lower(substr(first, 1, 1) || last),
11 'ĐŠŽĆČđšžćč',
12 'DSZCCdszcc'
13 ) val
14 from test
15 )
16 select id,
17 val || case when row_number() over (partition by val order by id) = 1 then null
18 else row_number() over (partition by val order by id)
19 end as result
20 from tuser
21 order by id;
ID RESULT
---------- --------------------
1 ihorvat
2 mhorvat
3 ibabic
4 tjurisic
5 ihorvat2
SQL>
【讨论】:
【参考方案2】:这是一种可能的解决方案,但请注意,它不是最佳解决方案,并且在大型表上表现不佳!
DECLARE
CURSOR c_users IS SELECT id, TRANSLATE(LOWER(SUBSTR(first,1,1) || last), 'ćčđšž', 'ccdsz') name FROM users;
TYPE ty_users IS TABLE OF c_users%rowtype;
t_users ty_users;
v_count NUMBER;
BEGIN
OPEN c_users;
FETCH c_users BULK COLLECT INTO t_users;
CLOSE c_users;
FOR i IN t_users.FIRST..t_users.LAST LOOP
IF t_users.EXISTS(i) THEN
v_count := 0;
FOR j IN 1..i LOOP
IF t_users.EXISTS(i) AND t_users(i).name = t_users(j).name AND i <> j THEN
v_count := v_count + 1;
END IF;
END LOOP;
IF v_count > 0 THEN
t_users(i).name := t_users(i).name || v_count;
END IF;
END IF;
END LOOP;
IF t_users.COUNT > 0 THEN
FORALL indx IN INDICES OF t_users
UPDATE users SET username = t_users(indx).name WHERE id = t_users(indx).id;
END IF;
END;
【讨论】:
以上是关于Oracle PL/SQL如何连接一行和另一行中值的第一个字母的主要内容,如果未能解决你的问题,请参考以下文章
如何在 oracle pl sql 中使用 LAG 函数,直到到达非零或最后一行?
为啥mssql的OPENQUERY取oracle某表时只返回了一行数据,而在pl/sql中可以查到表中有两行数据,求解答?