如何优化扩展分隔列表的查询?

时间:2018-01-15 16:30:09

标签: oracle

我是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
 ...

据我所知,它将分隔的列表扩展为唯一的行,然后将其与每个名称的以下表格连接起来,但我不确定它是否全部都是这样的。这样做。如果是这种情况,有没有更好的方法来实现这一目标?

2 个答案:

答案 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