Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle-Abfrage, um alle Werte in der Liste mit allen Zeilen in der Tabelle abzugleichen

Oracle-Setup :

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;

Abfrage - Verwenden Sie GROUP BY und 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

Ausgabe :

A
-
a

Abfrage - Dynamische Übergabe der 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 );

Wo die Bind-Variable :your_list ist vom Typ stringlist .

Wenn die Liste als Zeichenfolge mit Trennzeichen übergeben wird, können Sie eine der Techniken in Aufteilen von Zeichenfolgen mit Trennzeichen Dokumentationsseite, um es zu trennen. Es gibt eine einfache PL/SQL-Funktion das würde es als Sammlung zurückgeben, die in die obige Abfrage eingefügt werden könnte.

Aktualisieren :

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;

oder

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;