我是Oracle新手,最近遇到了以下问题。我试图了解它正在做什么,并希望重写它以优化它。在这个例子中,:NameList将是一个以逗号分隔的列表(如:" Bob,Bill,Fred")然后:N_NameList将是令牌的数量(在上面的示例中为3)
SELECT ... FROM
(
SELECT
REGEXP_SUBSTR(:NameList,'[^,]+',1,LEVEL, 'i') Name
FROM DUAL CONNECT BY LEVEL <= :N_NameList
) x
INNER JOIN PEOPLE ppl
ON ppl.Name LIKE x.Name
...
据我所知,它将分隔的列表扩展为唯一的行,然后将其与每个名称的以下表格连接起来,但我不确定它是否全部都是这样的。这样做。如果是这种情况,有没有更好的方法来实现这一目标?
答案 0 :(得分:1)
您可以尝试这样做:
select ...
from people ppl
where instr (','||:NameList||',',
','||ppl.name||',') > 0;
答案 1 :(得分:0)
有更好的方法来实现这个目标吗?
好吧,你可以摆脱N_NameList,因为你可以很容易地计算令牌的数量。这并不意味着它是更好的方式,它只是一个不同的选项。说实话,它可能比你的慢选项,因为我必须计算你作为参数输入的东西。
由于此示例基于SQLPlus,我使用&
而不是:
作为替换变量。 &&
表示它“记住”之前输入的值(否则,我应该两次输入NameList。
您当前的疑问:
SQL> select regexp_substr('&namelist', '[^,]+', 1, level, 'i') name
2 from dual
3 connect by level <= &n_namelist;
Enter value for namelist: Bob,Bill,Fred
Enter value for n_namelist: 3
Bob
Bill
Fred
计算 N_NameList (使用REGEXP_COUNT
):
SQL> select regexp_substr('&&namelist', '[^,]+', 1, level, 'i') name
2 from dual
3 connect by level <= regexp_count('&&namelist', ',') + 1;
Enter value for namelist: Bob,Bill,Fred
Bob
Bill
Fred