Oracle
 sql >> Base de données >  >> RDS >> Oracle

Requête Oracle pour faire correspondre toutes les valeurs de la liste parmi toutes les lignes de la table

Configuration d'Oracle :

CREATE TABLE table_name ( ID, A, B ) AS
SELECT 1,    'a',     'a1' FROM DUAL UNION ALL
SELECT 2,    'b',     'b1' FROM DUAL UNION ALL
SELECT 3,    'a',     'a2' FROM DUAL UNION ALL
SELECT 4,    'c',     'a1' FROM DUAL UNION ALL
SELECT 5,    'b',     'b2' FROM DUAL;

Requête – Utiliser GROUP BY et COUNT( DISTINCT ... ) :

SELECT A
FROM   table_name
WHERE  B IN ( 'a1', 'a2' )      -- The items in the list
GROUP BY A
HAVING COUNT( DISTINCT b ) = 2; -- The number of items in the list

Sortie :

A
-
a

Requête - Transmission dynamique de la liste :

CREATE OR REPLACE TYPE stringlist IS TABLE OF VARCHAR2(10);
/

SELECT A
FROM   table_name
WHERE  B MEMBER OF :your_list
GROUP BY A
HAVING COUNT( DISTINCT B ) = CARDINALITY( :your_list );

Où la variable de liaison :your_list est de type stringlist .

Si la liste est transmise sous forme de chaîne délimitée, vous pouvez utiliser l'une des techniques du Fractionner des chaînes délimitées page de documentation pour le séparer. Il existe une simple fonction PL/SQL qui le renverrait sous la forme d'une collection pouvant être connectée à la requête ci-dessus.

Mettre à jour :

SELECT A
FROM   table_name
GROUP BY A
HAVING COUNT( DISTINCT CASE WHEN b IN ( 'a1', 'a2' )     THEN b END ) = 2
AND    COUNT( DISTINCT CASE WHEN b NOT IN ( 'a1', 'a2' ) THEN b END ) = 0;

ou

SELECT A
FROM   table_name
GROUP BY A
HAVING COUNT( DISTINCT CASE WHEN b MEMBER OF :your_list     THEN b END ) = CARDINALITY( :your_list )
AND    COUNT( DISTINCT CASE WHEN b NOT MEMBER OF :your_list THEN b END ) = 0;