在SQL/Oracle中从一列中搜索另一列中的文本

ecfdbz9o  于 2023-10-16  发布在  Oracle
关注(0)|答案(4)|浏览(125)

我有两个专栏
| 用户名|管理员列表|
| --|--|
| Abhi| Ayush; Abhi;格尔登|
| 苏曼|Ayush; Priti;格尔登|
| Satish| Ayush; Priti;克立提|
我想看看用户名中的用户是否存在于Oracle SQL中的ManagerList中
输出
| 用户名|管理员列表|is_available|
| --|--|--|
| Abhi| Ayush; Abhi;格尔登|Y|
| 苏曼|Ayush; Priti;格尔登|N|
| Satish| Ayush; Priti;克立提|Y|

azpvetkf

azpvetkf1#

我们可以使用INSTR函数:

SELECT 
  UserName, ManagerList, 
  CASE WHEN INSTR(ManagerList,UserName) > 0  
    THEN 'Y'
    ELSE 'N' END AS is_available
FROM yourtable;

阅读文档中的函数。
根据您的数据查看此sample fiddle
注意:@Littlefoot提出了一种更清晰的方法来使用这个用例中的函数,请参阅this answer。我不知道你是否需要这样做,但这样更安全。

juud5qan

juud5qan2#

注意instrlike的 * 误报 *。我不知道这是否可能,但是-如果有人(经理)有一个以上的名字(这可能是;有些人有不止一个名字),你会得到错误的结果。举例来说:

SQL> WITH
  2     test (username, managerlist)
  3     AS
  4        (SELECT 'Abhi', 'Ayush Abhi Priti; Kirti; Satish' FROM DUAL)
  5  SELECT UserName,
  6         ManagerList,
  7         CASE WHEN INSTR (ManagerList, UserName) > 0 THEN 'Y' ELSE 'N' END
  8            AS is_available_instr,              --> Jonas
  9         CASE WHEN ManagerList LIKE '%' || UserName || '%' THEN 'Y' ELSE 'N' END
 10            is_available_like                   --> Ankit
 11    FROM test;

USERNAME        MANAGERLIST                     IS_AVAILABLE_INSTR   IS_AVAILABLE_LIKE
--------------- ------------------------------- -------------------- --------------------
Abhi            Ayush Abhi Priti; Kirti; Satish Y                    Y

SQL>

看到了吗?名为“Ayush Abhi Priti”的管理器确实包含“Abhi”,但是-在这种情况下,Y是正确的结果吗?
考虑应用分隔符来避免这样的结果:

SQL> WITH
  2     test (username, managerlist)
  3     AS
  4        (SELECT 'Abhi', 'Ayush; Abhi; Kirti' FROM DUAL
  5         UNION ALL
  6         SELECT 'Suman', 'Ayush; Priti; Kirti' FROM DUAL
  7         UNION ALL
  8         SELECT 'Satish', 'Ayush; Priti; Kirti; Satish' FROM DUAL
  9         UNION ALL
 10         SELECT 'Abhi', 'Ayush Abhi Priti; Kirti; Satish' FROM DUAL)
 11  SELECT username,
 12         managerlist,
 13         --
 14         CASE
 15            WHEN INSTR (';' || managerlist || ';', '; ' || username || ';') > 0 THEN 'Y'
 16            ELSE 'N'
 17         END AS is_available
 18    FROM test;

USERNAME        MANAGERLIST                     IS_AVAILABLE
--------------- ------------------------------- ---------------
Abhi            Ayush; Abhi; Kirti              Y
Suman           Ayush; Priti; Kirti             N
Satish          Ayush; Priti; Kirti; Satish     Y
Abhi            Ayush Abhi Priti; Kirti; Satish N     --> previously, this one was wrong, marked as "Y"

SQL>
de90aj5v

de90aj5v3#

我认为简单的LIKE操作符将为您工作-

SELECT UserName, ManagerList, CASE WHEN ManagerList LIKE '%' || UserName  || '%' THEN
                                        'Y'
                                   ELSE 'N'
                              END is_available
  FROM your_table;

Demo.

s4chpxco

s4chpxco4#

使用LIKEINSTRmanagerlist与用户名进行比较包括两个字符的周围字符:

SELECT username,
       managerlist, 
       CASE
       WHEN '; ' || managerlist || '; ' LIKE '%; ' || username || '; %'
       THEN 'Y'
       ELSE 'N'
       END AS is_available
FROM   table_name

或:

SELECT username,
       managerlist, 
       CASE
       WHEN INSTR('; ' || managerlist || '; ', '; ' || username || '; ') > 0
       THEN 'Y'
       ELSE 'N'
       END AS is_available
FROM   table_name

其中,对于样本数据:

CREATE TABLE table_name (UserName, ManagerList) AS
SELECT 'Alice', 'Beryl; Alice; Carol' FROM DUAL UNION ALL
SELECT 'Beryl', 'Alice; Carol; Debra' FROM DUAL UNION ALL
SELECT 'Carol', 'Beryl; Alice; Carol' FROM DUAL UNION ALL
SELECT 'Alice', 'Beryl; NotAlice; Carol' FROM DUAL

输出:
| 用户名|企业简介|是否可用|
| --|--|--|
| 爱丽丝|绿柱石;爱丽丝;卡罗尔|Y|
| 绿柱石|爱丽丝;卡罗尔;黛布拉|N|
| 卡罗尔|绿柱石;爱丽丝;卡罗尔|Y|
| 爱丽丝|绿柱石;非爱丽丝;卡罗尔|N|
如果你只是使用INSTRLIKE来简单地匹配值 * 而不使用 * 周围的分隔符,那么当你匹配一个部分项时,你可能会得到假阳性,当你只匹配Alice时,你会匹配NotAlice。包含分隔符将强制匹配为完整的项。
fiddle

相关问题