重写 NOT IN,但子查询涉及逗号分隔的字符串(ID)
Rewrite NOT IN, but subquery involves a comma seperated string (ID)
使用 SQL Developer 更改 Oracle 存储过程。
输入:逗号分隔的 ID。 (示例:'P23,P37,P39,P45')
编辑:请注意输入的是字符串,不是字符串数组。此外,该字符串可能不仅仅是 4 个 ID。可能会上升到 200 左右。
想从没有这些输入 ID 的 table 中找出。
以下太慢了。只有大约 300 行数据(在 table 中)但需要大约 20 秒。所以我想重写。请给我一些关于如何做的提示。
ID_Array 是 'P23,P37,P39,P45'.
SELECT * FROM StudentInfo
WHERE StudentClass = 'Primary5A'
AND StudentID NOT IN
(
SELECT REGEXP_SUBSTR(ID_Array, '[^,]+', 1, LEVEL) StudentID
FROM DUAL
CONNECT BY REGEXP_SUBSTR(ID_Array, '[^,]+', 1, LEVEL) IS NOT NULL
)
AND Height <= 150;
有些人可能已经知道了。以下
SELECT REGEXP_SUBSTR(ID_Array, '[^,]+', 1, LEVEL) StudentID
FROM DUAL
CONNECT BY REGEXP_SUBSTR(ID_Array, '[^,]+', 1, LEVEL) IS NOT NULL
会将 ID_Array 变成一个 table(table 类结构?)有四行:
+-----+
| P23 |
| P37 |
| P39 |
| P45 |
+-----+
你的 ID_Array 一定比你这里的例子长很多。 'P23,P37,P39,P45' 我的表现非常好。
如果字符串较长,REGEXP_SUBSTR
会变得很慢。我建议尽可能使用 LIKE
,即使它变得很奇怪。试试这个。
SELECT * FROM StudentInfo
WHERE StudentClass = 'Primary5A'
AND ','||ID_Array||',' NOT LIKE '%,'||StudentID||',%'
AND Height <= 150;
即使您使用的是正则表达式,也无需使用 CONNECT BY
。您可以使用 LIKE
或 REGEXP_LIKE()
:
SELECT * FROM studentinfo
WHERE studentclass = 'Primary5A'
AND height <= 150
AND NOT REGEXP_LIKE(','||id_array||',', ','||studentid||',');
我猜 id_array
本身不够短,不能用作正则表达式模式(300 行?)。如果是,您可以执行以下操作:
SELECT * FROM studentinfo
WHERE studentclass = 'Primary5A'
AND height <= 150
AND NOT REGEXP_LIKE(student_id, '^(' || REPLACE(id_array, ',', '|') || ')$');
但我认为 Oracle 中的正则表达式模式限制为 512 个字节。
使用 SQL Developer 更改 Oracle 存储过程。
输入:逗号分隔的 ID。 (示例:'P23,P37,P39,P45') 编辑:请注意输入的是字符串,不是字符串数组。此外,该字符串可能不仅仅是 4 个 ID。可能会上升到 200 左右。
想从没有这些输入 ID 的 table 中找出。
以下太慢了。只有大约 300 行数据(在 table 中)但需要大约 20 秒。所以我想重写。请给我一些关于如何做的提示。
ID_Array 是 'P23,P37,P39,P45'.
SELECT * FROM StudentInfo
WHERE StudentClass = 'Primary5A'
AND StudentID NOT IN
(
SELECT REGEXP_SUBSTR(ID_Array, '[^,]+', 1, LEVEL) StudentID
FROM DUAL
CONNECT BY REGEXP_SUBSTR(ID_Array, '[^,]+', 1, LEVEL) IS NOT NULL
)
AND Height <= 150;
有些人可能已经知道了。以下
SELECT REGEXP_SUBSTR(ID_Array, '[^,]+', 1, LEVEL) StudentID
FROM DUAL
CONNECT BY REGEXP_SUBSTR(ID_Array, '[^,]+', 1, LEVEL) IS NOT NULL
会将 ID_Array 变成一个 table(table 类结构?)有四行:
+-----+
| P23 |
| P37 |
| P39 |
| P45 |
+-----+
你的 ID_Array 一定比你这里的例子长很多。 'P23,P37,P39,P45' 我的表现非常好。
如果字符串较长,REGEXP_SUBSTR
会变得很慢。我建议尽可能使用 LIKE
,即使它变得很奇怪。试试这个。
SELECT * FROM StudentInfo
WHERE StudentClass = 'Primary5A'
AND ','||ID_Array||',' NOT LIKE '%,'||StudentID||',%'
AND Height <= 150;
即使您使用的是正则表达式,也无需使用 CONNECT BY
。您可以使用 LIKE
或 REGEXP_LIKE()
:
SELECT * FROM studentinfo
WHERE studentclass = 'Primary5A'
AND height <= 150
AND NOT REGEXP_LIKE(','||id_array||',', ','||studentid||',');
我猜 id_array
本身不够短,不能用作正则表达式模式(300 行?)。如果是,您可以执行以下操作:
SELECT * FROM studentinfo
WHERE studentclass = 'Primary5A'
AND height <= 150
AND NOT REGEXP_LIKE(student_id, '^(' || REPLACE(id_array, ',', '|') || ')$');
但我认为 Oracle 中的正则表达式模式限制为 512 个字节。