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中可以查到表中有两行数据,求解答?

如何在 Oracle PL/SQL 过程的开始部分之后声明游标

“如何修复 oracle pl/sql 中的触发器?

PL/SQL UTL_FILE:循环如何自动返回下一行?

如何配置pl/sql 连接远程oracle服务器