2017-12-21 7 views
1

Ich habe drei Tabellen:finden Kombinationen aus zwei Tabellen, die in dritter Tabelle nicht existieren

Tabelle A (> 1.000.000 Zeilen)

+----+-----------+ 
| id | field_A_1 | 
+----+-----------+ 
| 1 | testa1 | 
| 2 | testa2 | 
| 3 | testa3 | 
+----+-----------+ 

Tabelle B (~ 100 Zeilen)

+----+-----------+ 
| id | field_B_1 | 
+----+-----------+ 
| 1 | testb1 | 
| 2 | testb2 | 
| 3 | testb3 | 
+----+-----------+ 

Tabelle C (> 10.000.000 Zeilen)

+----+---------------+---------------+ 
| id | field_A_1  | fk_id_table_B | 
+----+---------------+---------------+ 
| 1 |  testa1 |    1 | 
| 2 |  testa2 |    2 | 
| 3 |  testa3 |    3 | 
+----+---------------+---------------+ 

Ich möchte alle Kombinationen von A und B finden, die nicht in Tabelle C sind. Leider Tabelle A Feld_A_1/Tabelle C Feld_A_1 sind Varchar.

Ergebnis würde für dieses Beispiel sein:

+-----------+---------------+ 
| field_A_1 | fk_id_table_B | 
+-----------+---------------+ 
| testa1 |    2 | 
| testa1 |    3 | 
| testa2 |    1 | 
| testa2 |    3 | 
| testa3 |    1 | 
| testa3 |    2 | 
+-----------+---------------+ 

Ergebnisse von Antworten:

EXPLAIN 
SELECT count(a.field_A_1), 
     b.id AS fk_id_table_B 
FROM a, 
CROSS JOIN b 
WHERE NOT EXISTS 
    (SELECT 1 
    FROM c 
    WHERE c.field_A_1=a.field_A_1 
     AND fk_id_table_B=b.id) 
GROUP BY fk_id_table_B 

+----+--------------------+-------+-------+----------------------------+----------------------------+---------+------------------+------------+----------------------------------------------------+ 
| id | select_type  | table | type |  possible_keys  |   key    | key_len |  ref  | rows |      Extra      | 
+----+--------------------+-------+-------+----------------------------+----------------------------+---------+------------------+------------+----------------------------------------------------+ 
| 1 | PRIMARY   | b  | index | PRIMARY,b.id_foreign  | b.id_foreign    | 4  | NULL    | ~100  | Using index; Using temporary; Using filesort  | 
| 1 | PRIMARY   | a  | ALL | NULL      | NULL      | NULL | NULL    | >1.000.000 | Using where; Using join buffer (Block Nested Loop) | 
| 2 | DEPENDENT SUBQUERY | c  | ref | IDX_TABLE_C_B_ID_FIELD_A_1 | IDX_TABLE_C_B_ID_FIELD_A_1 | 36  | b.id,a.field_A_1 | 4   | Using index          | 
+----+--------------------+-------+-------+----------------------------+----------------------------+---------+------------------+------------+----------------------------------------------------+ 

Laufzeit unbekannt ich die Abfrage nach einer Minute getötet, das Senden von Daten zu lange gedauert hat.

Laufzeit unbekannt Ich habe die Abfrage nach einer Minute abgebrochen, das Senden von Daten dauerte zu lange.

+0

Was ist die erwartete Ergebnismenge von fo r die in der Frage geposteten Daten? –

+0

fügen Sie bitte die Abfrage an, die Sie bisher versucht haben .. – Laxmi

Antwort

2

Sie können dies tun:

SELECT t1.* 
FROM 
(
    SELECT field_A_1, b.id as bid 
    FROM TableA as a, TableB as b 
) AS t1 
LEFT JOIN TableC AS c ON t1.field_A_1 = c.field_A_1 AND t1.bid = c.fk_id_table_B 
WHERE c.field_A_1 IS NULL AND c.fk_id_table_B is null; 

Die Cross-Join zwischen Tabelle a und b FROM TableA as a, TableB as b erhalten Sie alle möglichen Kombinationen zwischen den beiden Tabellen.

Dann mit LEFT JOIN mit Tabelle c und mit IS NULL Prädikat können Sie nur die Kombinationen haben, die nicht in Tabelle c vorhanden sind. Da diese Kombinationen, die nicht vorhanden sind, Nullwerte für beide Join-Spalten haben.


Ergebnisse:

| field_A_1 | bid | 
|-----------|-----| 
| testa2 | 1 | 
| testa3 | 1 | 
| testa1 | 2 | 
| testa3 | 2 | 
| testa1 | 3 | 
| testa2 | 3 | 
1

Alle Kombinationen von A und B ist ein CROSS JOIN, verwenden Sie NICHT VORHANDEN sie zum Filtern:

select a.field_A_1, b.id as fk_id_table_B 
    from a, cross join b 
where not exists (select 1 from c where c.field_A_1=a.field_A_1 
            and fk_id_table_B=b.id) 
Verwandte Themen