【问题标题】:Oracle PL/SQL how to join first letter of value in a row and another rowOracle PL/SQL如何连接一行和另一行中值的第一个字母
【发布时间】: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,我了解函数,但我不知道如何组合它们。在哪个模块以及如何。

标签: sql oracle join


【解决方案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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多