替代MySQL中的Intersect

Ank*_*ala 60 mysql intersect

我需要在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='??') )
Run Code Online (Sandbox Code Playgroud)

我知道相交不在MySQL中.所以我需要另一种方式.请指导我.

Mik*_*ike 55

Microsoft SQL Server "返回由INTERSECT操作数左侧和右侧的查询返回的任何不同值" 这与标准或查询不同.INTERSECT INNER JOINWHERE EXISTS

SQL Server

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)
Run Code Online (Sandbox Code Playgroud)

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     |
+-------+
Run Code Online (Sandbox Code Playgroud)

With this particular question, the id column is involved, so duplicate values will not be returned, but for the sake of completeness, here's a MySQL alternative using INNER JOIN and DISTINCT:

SELECT DISTINCT value FROM table_a
INNER JOIN table_b
USING (value);

+-------+
| value |
+-------+
| B     |
+-------+
Run Code Online (Sandbox Code Playgroud)

And another example using WHERE ... IN and DISTINCT:

SELECT DISTINCT value FROM table_a
WHERE (value) IN
(SELECT value FROM table_b);

+-------+
| value |
+-------+
| B     |
+-------+
Run Code Online (Sandbox Code Playgroud)

  • 围绕"价值"的括号为什么? (2认同)

FBB*_*FBB 37

通过使用UNION ALL和GROUP BY,有一种更有效的生成交叉的方法.根据我对大型数据集的测试,性能提高了两倍.

例:

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;
Run Code Online (Sandbox Code Playgroud)

它更有效,因为使用INNER JOIN解决方案,MySQL将查找第一个查询的结果,然后对于每一行,在第二个查询中查找结果.使用UNION ALL-GROUP BY解决方案,它将查询第一个查询的结果,第二个查询的结果,然后将结果一起分组.

  • @ code2be:这就是重点,你不想删除重复项,以便能够计算结果数,并满足条件`HAVING count(*)> = 2`.如果你不使用`UNION ALL`,这将不起作用. (5认同)
  • 这也将返回仅在其中一个表中重复的值. (2认同)

Qua*_*noi 15

您的查询将始终返回空记录集,因为cut_name= '?????' and cut_name='??'永远不会评估true.

一般情况下,INTERSECTMySQL应该仿效这样的:

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))
        )
Run Code Online (Sandbox Code Playgroud)

如果两个表都标记为列NOT NULL,则可以省略这些IS NULL部分并以稍高效的方式重写查询IN:

SELECT  *
FROM    mytable m
WHERE   (col1, col2, col3) IN
        (
        SELECT  col1, col2, col3
        FROM    othertable o
        )
Run Code Online (Sandbox Code Playgroud)


Pay*_*yam 5

我刚刚在 MySQL 5.7 中检查了它,我真的很惊讶没有人提供一个简单的答案:NATURAL JOIN

当表或(选择结果)具有 IDENTICAL 列时,您可以使用 NATURAL JOIN 作为查找交集的方法:

在此处输入图片说明

例如:

表1

身份证号、姓名、工作号

“1”、“约翰”、“1”

“2”、“杰克”、“3”

“3”、“亚当”、“2”

“4”、“比尔”、“6”

表2

身份证号、姓名、工作号

“1”、“约翰”、“1”

“2”、“杰克”、“3”

“3”、“亚当”、“2”

“4”、“比尔”、“5”

“5”、“最大”、“6”

这是查询:

SELECT * FROM table1 NATURAL JOIN table2;
Run Code Online (Sandbox Code Playgroud)

查询结果: id、name、jobid

“1”、“约翰”、“1”

“2”、“杰克”、“3”

“3”、“亚当”、“2”