Alternative à Intersect dans MySQL

Je dois implémenter la requête suivante dans MySQL.

(select * from emovis_reporting where (id=3 and cut_name= '全プロセス' and cut_name='恐慌') ) intersect ( select * from emovis_reporting where (id=3) and ( cut_name='全プロセス' or cut_name='恐慌') ) 

Je sais que l’intersection n’est pas dans MySQL. J’ai donc besoin d’un autre moyen. Guidez-moi s’il-vous-plaît.

    INTERSECT de Microsoft SQL Server “renvoie toutes les valeurs distinctes renvoyées à la fois par la requête à gauche et à droite de l’opérande INTERSECT”. Ceci est différent d’une requête INNER JOIN ou WHERE EXISTS standard.

    serveur SQL

     CREATE TABLE table_a ( id INT PRIMARY KEY, value VARCHAR(255) ); CREATE TABLE table_b ( id INT PRIMARY KEY, value VARCHAR(255) ); INSERT INTO table_a VALUES (1, 'A'), (2, 'B'), (3, 'B'); INSERT INTO table_b VALUES (1, 'B'); SELECT value FROM table_a INTERSECT SELECT value FROM table_b value ----- B (1 rows affected) 

    MySQL

     CREATE TABLE `table_a` ( `id` INT NOT NULL AUTO_INCREMENT, `value` varchar(255), PRIMARY KEY (`id`) ) ENGINE=InnoDB; CREATE TABLE `table_b` LIKE `table_a`; INSERT INTO table_a VALUES (1, 'A'), (2, 'B'), (3, 'B'); INSERT INTO table_b VALUES (1, 'B'); SELECT value FROM table_a INNER JOIN table_b USING (value); +-------+ | value | +-------+ | B | | B | +-------+ 2 rows in set (0.00 sec) SELECT value FROM table_a WHERE (value) IN (SELECT value FROM table_b); +-------+ | value | +-------+ | B | | B | +-------+ 

    Avec cette question particulière, la colonne id est impliquée, donc les valeurs dupliquées ne seront pas retournées, mais pour être complet, voici une alternative MySQL utilisant INNER JOIN et DISTINCT :

     SELECT DISTINCT value FROM table_a INNER JOIN table_b USING (value); +-------+ | value | +-------+ | B | +-------+ 

    Et un autre exemple utilisant WHERE ... IN et DISTINCT :

     SELECT DISTINCT value FROM table_a WHERE (value) IN (SELECT value FROM table_b); +-------+ | value | +-------+ | B | +-------+ 

    Il existe un moyen plus efficace de générer une intersection, en utilisant UNION ALL et GROUP BY. Les performances sont deux fois meilleures selon mes tests sur de grands ensembles de données.

    Exemple:

     SELECT t1.value from ( (SELECT DISTINCT value FROM table_a) UNION ALL (SELECT DISTINCT value FROM table_b) ) AS t1 GROUP BY value HAVING count(*) >= 2; 

    C’est plus efficace, car avec la solution INNER JOIN, MySQL recherchera les résultats de la première requête, puis pour chaque ligne, rechercher le résultat dans la deuxième requête. Avec la solution UNION ALL-GROUP BY, elle interrogera les résultats de la première requête, les résultats de la deuxième requête, puis regroupera les résultats tous en même temps.

    Votre requête renverrait toujours un jeu d’enregistrements vide car cut_name= '全プロセス' and cut_name='恐慌' ne seront jamais évalués à true .

    En général, INTERSECT dans MySQL devrait être émulé comme ceci:

     SELECT * FROM mytable m WHERE EXISTS ( SELECT NULL FROM othertable o WHERE (o.col1 = m.col1 OR (m.col1 IS NULL AND o.col1 IS NULL)) AND (o.col2 = m.col2 OR (m.col2 IS NULL AND o.col2 IS NULL)) AND (o.col3 = m.col3 OR (m.col3 IS NULL AND o.col3 IS NULL)) ) 

    Si vos deux colonnes ont des colonnes marquées comme NOT NULL , vous pouvez omettre les parties IS NULL et réécrire la requête avec un IN légèrement plus efficace:

     SELECT * FROM mytable m WHERE (col1, col2, col3) IN ( SELECT col1, col2, col3 FROM othertable o ) 

    Je viens de le vérifier en MySQL 5.7 et je suis vraiment surpris de voir à quel point personne n’a offert une réponse simple: NATURAL JOIN

    Lorsque les tables ou (select result) ont des colonnes IDENTICAL, vous pouvez utiliser NATURAL JOIN pour trouver une intersection:

    entrer la description de l'image ici

    Par exemple:

    table1 :

    id, nom, jobid

    ‘1’, ‘John’, ‘1’

    ‘2’, ‘Jack’, ‘3’

    ‘3’, ‘Adam’, ‘2’

    ‘4’, ‘Bill’, ‘6’

    table2 :

    id, nom, jobid

    ‘1’, ‘John’, ‘1’

    ‘2’, ‘Jack’, ‘3’

    ‘3’, ‘Adam’, ‘2’

    ‘4’, ‘Bill’, ‘5’

    ‘5’, ‘Max’, ‘6’

    Et voici la requête:

     SELECT * FROM table1 NATURAL JOIN table2; 

    Résultat de la requête: id, nom, jobid

    ‘1’, ‘John’, ‘1’

    ‘2’, ‘Jack’, ‘3’

    ‘3’, ‘Adam’, ‘2’

    Pour être complet, voici une autre méthode pour émuler INTERSECT . Notez que le formulaire IN (SELECT ...) proposé dans d’autres réponses est généralement plus efficace.

    Généralement pour une table appelée mytable avec une clé primaire appelée id :

     SELECT id FROM mytable AS a INNER JOIN mytable AS b ON a.id = b.id WHERE (a.col1 = "someval") AND (b.col1 = "someotherval") 

    (Notez que si vous utilisez SELECT * avec cette requête, vous obtiendrez deux fois plus de colonnes que celles définies dans mytable , car INNER JOIN génère un produit cartésien )

    INNER JOIN génère ici toutes les permutations de paires de lignes de votre table. Cela signifie que chaque combinaison de lignes est générée, dans tous les ordres possibles. La clause WHERE filtre alors a côté de la paire, puis le côté b . Le résultat est que seules les lignes qui satisfont aux deux conditions sont renvoyées, comme le feraient deux requêtes d’intersection.

    Casser votre problème en 2 phrases: premièrement, vous voulez tout sélectionner si

     (id=3 and cut_name= '全プロセス' and cut_name='恐慌') 

    est vrai . Deuxièmement, vous voulez tout sélectionner si

     (id=3) and ( cut_name='全プロセス' or cut_name='恐慌') 

    est vrai. Donc, nous allons rejoindre à la fois par OR parce que nous voulons tout sélectionner si l’un d’entre eux est vrai.

     select * from emovis_reporting where (id=3 and cut_name= '全プロセス' and cut_name='恐慌') OR ( (id=3) and ( cut_name='全プロセス' or cut_name='恐慌') ) 

    AFAIR, MySQL implémente INTERSECT via INNER JOIN .

     SELECT campo1, campo2, campo3, campo4 FROM tabela1 WHERE CONCAT(campo1,campo2,campo3,IF(campo4 IS NULL,'',campo4)) NOT IN (SELECT CONCAT(campo1,campo2,campo3,IF(campo4 IS NULL,'',campo4)) FROM tabela2);