J'ai besoin d'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. Il me faut donc un autre moyen… .. S'il vous plaît, guide-moi.
La variable INTERSECT
"de Microsoft SQL Server renvoie toutes les valeurs distinctes renvoyées par la requête située à gauche et à droite de l'opérande INTERSECT" Ceci est différent d'une requête standard INNER JOIN
ou WHERE EXISTS
.
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, ainsi les valeurs en double ne seront pas renvoyées. Toutefois, par souci d'exhaustivité, 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 des jeux de données volumineux.
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, recherchera le résultat dans la seconde requête. Avec la solution UNION ALL-GROUP BY, il interroge les résultats de la première requête, les résultats de la seconde requête, puis les regroupe tous en même temps.
Votre requête renverra toujours un jeu d'enregistrements vide, car cut_name= '全プロセス' and cut_name='恐慌'
ne sera jamais évalué à true
.
En général, INTERSECT
dans MySQL
devrait être imité 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 les colonnes de vos deux tables sont marquées NOT NULL
, vous pouvez omettre les parties IS NULL
et réécrire la requête avec une variable 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 dans MySQL 5.7 et je suis vraiment surpris de constater que personne ne propose une réponse simple: NATURAL JOIN
Lorsque les tables ou (sélectionnez le résultat) ont des colonnes IDENTICAL, vous pouvez utiliser NATURAL JOIN comme moyen de rechercher l'intersection:
Par exemple:
Tableau 1:
identifiant, nom, jobid
'1', 'John', '1'
'2', 'Jack', '3'
'3', 'Adam', '2'
'4', 'Bill', '6'
Tableau 2:
identifiant, 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: identifiant, nom, jobid
'1', 'John', '1'
'2', 'Jack', '3'
'3', 'Adam', '2'
Pour compléter, voici une autre méthode pour émuler INTERSECT
. Notez que le formulaire IN (SELECT ...)
suggéré 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 )
Le INNER JOIN
ici génère chaque permutation de paires de lignes de votre table. Cela signifie que chaque combinaison de lignes est générée, dans chaque ordre possible. La clause WHERE
filtre ensuite le côté a
de la paire, puis le côté b
. Le résultat est que seules les lignes satisfaisant les deux conditions sont renvoyées, exactement comme le feraient deux requêtes à l'intersection.
Brisez votre problème en 2 déclarations: 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. Nous allons donc rejoindre les deux par OR car nous souhaitons tout sélectionner si l’un d’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='恐慌') )