sql >> Database >  >> RDS >> Oracle

SELECTEER uit tabel met Varying IN-lijst in WHERE-clausule

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.


  1. Hoe te schrijven met BCP naar een externe SQL Server?

  2. Hoe de Where-clausule te gebruiken in Select-instructie in SQL Server - SQL Server / TSQL-zelfstudie, deel 109

  3. Soorten SQL-opdrachten

  4. Hoe om te gaan met database-evoluties van Play Framework 2 in productie