queries - mysql union
Alternativa para intersectar en MySQL (8)
AFAIR, MySQL implementa INTERSECT a través de INNER JOIN .
Necesito implementar la siguiente consulta en 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=''恐慌'') )
Sé que intersectar no está en MySQL. Entonces necesito otra forma. Por favor guíame.
Acabo de comprobarlo en MySQL 5.7 y estoy realmente sorprendido de que nadie haya ofrecido una respuesta simple: NATURAL JOIN
Cuando las tablas o (seleccionar resultado) tienen columnas IDENTICAS, puede usar NATURAL JOIN como una forma de encontrar intersección:
Por ejemplo:
mesa1 :
id, nombre, jobid
''1'', ''John'', ''1''
''2'', ''Jack'', ''3''
''3'', ''Adam'', ''2''
''4'', ''Bill'', ''6''
tabla2 :
id, nombre, jobid
''1'', ''John'', ''1''
''2'', ''Jack'', ''3''
''3'', ''Adam'', ''2''
''4'', ''Bill'', ''5''
''5'', ''Max'', ''6''
Y aquí está la consulta:
SELECT * FROM table1 NATURAL JOIN table2;
Resultado de la consulta: id, name, jobid
''1'', ''John'', ''1''
''2'', ''Jack'', ''3''
''3'', ''Adam'', ''2''
Divide tu problema en 2 afirmaciones: en primer lugar, quieres seleccionar todo si
(id=3 and cut_name= ''全プロセス'' and cut_name=''恐慌'')
es verdad . En segundo lugar, desea seleccionar todo si
(id=3) and ( cut_name=''全プロセス'' or cut_name=''恐慌'')
es verdad. Entonces, nos uniremos a ambos por O porque queremos seleccionar todo si alguno de ellos es verdadero.
select * from emovis_reporting
where (id=3 and cut_name= ''全プロセス'' and cut_name=''恐慌'') OR
( (id=3) and ( cut_name=''全プロセス'' or cut_name=''恐慌'') )
Hay una forma más efectiva de generar una intersección, utilizando UNION ALL y GROUP BY. Las actuaciones son dos veces mejores de acuerdo con mis pruebas en grandes conjuntos de datos.
Ejemplo:
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;
Es más efectivo, porque con la solución INNER JOIN, MySQL buscará los resultados de la primera consulta, y luego, para cada fila, buscará el resultado en la segunda consulta. Con la solución UNION ALL-GROUP BY, consultará los resultados de la primera consulta, los resultados de la segunda consulta y luego agrupará todos los resultados a la vez.
Para completar esto, hay otro método para emular INTERSECT
. Tenga en cuenta que el formulario IN (SELECT ...)
sugerido en otras respuestas generalmente es más eficiente.
En general, para una tabla llamada mytable
con una clave principal llamada 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")
(Tenga en cuenta que si utiliza SELECT *
con esta consulta obtendrá el doble de columnas definidas en mytable
, esto es porque INNER JOIN
genera un producto cartesiano )
La INNER JOIN
aquí genera cada permutation de pares de filas de su tabla. Eso significa que se genera cada combinación de filas, en todos los órdenes posibles. La cláusula WHERE
luego filtra el lado a del par, luego el lado b
. El resultado es que solo se devuelven las filas que satisfacen ambas condiciones, al igual que las intersecciones que harían dos consultas.
Su consulta siempre devolverá un conjunto de registros vacío, ya que cut_name= ''全プロセス'' and cut_name=''恐慌''
nunca se evaluará como true
.
En general, INTERSECT
en MySQL
debe emularse así:
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 ambas tablas tienen columnas marcadas como NOT NULL
, puede omitir las partes IS NULL
y reescribir la consulta con una IN
ligeramente más eficiente:
SELECT *
FROM mytable m
WHERE (col1, col2, col3) IN
(
SELECT col1, col2, col3
FROM othertable o
)
INTERSECT
Microsoft SQL Server "devuelve valores distintos que son devueltos por la consulta en los lados izquierdo y derecho del operando INTERSECT" Esto es diferente de una consulta estándar INNER JOIN
o WHERE EXISTS
.
servidor 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 |
+-------+
Con esta pregunta en particular, la columna de identificación está involucrada, por lo que no se devolverán los valores duplicados, pero para completar, aquí hay una alternativa de MySQL que usa INNER JOIN
y DISTINCT
:
SELECT DISTINCT value FROM table_a
INNER JOIN table_b
USING (value);
+-------+
| value |
+-------+
| B |
+-------+
Y otro ejemplo usando WHERE ... IN
y DISTINCT
:
SELECT DISTINCT value FROM table_a
WHERE (value) IN
(SELECT value FROM table_b);
+-------+
| value |
+-------+
| B |
+-------+
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);