sql >> Base de Datos >  >> RDS >> Oracle

Consulta de Oracle para hacer coincidir todos los valores de la lista entre todas las filas de la tabla

Configuración de 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;

Consulta:use GROUP BY y 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

Salida :

A
-
a

Consulta - Pasar la lista dinámicamente :

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 );

Dónde está la variable de vinculación :your_list es de tipo stringlist .

Si la lista se pasa como una cadena delimitada, puede usar cualquiera de las técnicas en Dividir cadenas delimitadas página de documentación para separarlo. Hay una simple función PL/SQL eso lo devolvería como una colección que podría conectarse a la consulta anterior.

Actualizar :

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;

o

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;