Uw vereiste wordt genoemd als Varierende IN-lijsten . Zie Varierende IN-lijst met waarden in WHERE-clausule
Reden: IN ('1, 2, 3')
is NIET hetzelfde als IN (1, 2, 3)
OF IN('1', '2', '3')
Daarom
SELECT * FROM temp_id WHERE data_id IN (SELECT ids FROM temp);
is hetzelfde als
SELECT * FROM temp_id WHERE data_id IN('1, 2, 3');
wat een fout . zou opleveren ORA-01722: invalid number
-
SQL> SELECT * FROM temp_id WHERE data_id IN('1, 2, 3');
SELECT * FROM temp_id WHERE data_id IN('1, 2, 3')
*
ERROR at line 1:
ORA-01722: invalid number
SQL> SELECT * FROM temp_id WHERE data_id IN(SELECT ids FROM temp);
SELECT * FROM temp_id WHERE data_id IN(SELECT ids FROM temp)
*
ERROR at line 1:
ORA-01722: invalid number
NIET hetzelfde als
SELECTEER * FROM temp_id WHERE data_id IN (1, 2, 3);
wat je de juiste output zou geven -
SQL> SELECT * FROM temp_id WHERE data_id IN(1, 2, 3);
DATA_ID
----------
1
2
3
Oplossing:
Voor uw vereiste kunt u het als volgt bereiken -
SQL> SELECT * FROM temp;
IDS
--------------------------------------------------------------
1, 2, 3
SQL> SELECT * FROM temp_id;
DATA_ID
----------
1
2
3
4
5
SQL> WITH data AS
2 (SELECT to_number(trim(regexp_substr(ids, '[^,]+', 1, LEVEL))) ids
3 FROM temp
4 CONNECT BY instr(ids, ',', 1, LEVEL - 1) > 0
5 )
6 SELECT * FROM temp_id WHERE data_id IN
7 (SELECT ids FROM data
8 )
9 /
DATA_ID
----------
1
2
3
Als alternatief kunt u uw eigen TABEL-functie . maken of een Pipeline-functie om dit te behalen. Uw doel zou moeten zijn om de door komma's gescheiden IN-lijst op te splitsen in meerdere rijen . Hoe je het doet, is aan jou!
Werkende demo
Laten we een voorbeeld nemen van de standaard EMP tabel in SCOTT
schema.
Ik heb een lijst met banen in een string en ik wil de werknemers voor die banen tellen:
SQL> SET serveroutput ON
SQL> DECLARE
2 str VARCHAR2(100);
3 cnt NUMBER;
4 BEGIN
5 str := q'[CLERK,SALESMAN,ANALYST]';
6 SELECT COUNT(*) INTO cnt FROM emp WHERE JOB IN (str);
7 dbms_output.put_line('The total count is '||cnt);
8 END;
9 /
The total count is 0
PL/SQL procedure successfully completed.
Oh! Wat er is gebeurd? De standaard emp-tabel zou een output 10 moeten geven. De reden is dat de variërende IN-lijst .
Laten we eens kijken naar de juiste manier:
SQL> SET serveroutput ON
SQL> DECLARE
2 str VARCHAR2(100);
3 cnt NUMBER;
4 BEGIN
5 str := q'[CLERK,SALESMAN,ANALYST]';
6 SELECT COUNT(*)
7 INTO cnt
8 FROM emp
9 WHERE job IN
10 (SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL))
11 FROM dual
12 CONNECT BY instr(str, ',', 1, LEVEL - 1) > 0
13 );
14 dbms_output.put_line('The total count is '||cnt);
15 END;
16 /
The total count is 10
PL/SQL procedure successfully completed.