64

我需要在 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='恐慌') )

我知道 intersect 不在 MySQL 中。所以我需要另一种方式。请指导我。

4

8 回答 8

55

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

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     |
+-------+

对于这个特定的问题,涉及 id 列,因此不会返回重复的值,但为了完整起见,这里有一个 MySQL 替代方案,使用INNER JOINand DISTINCT

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

+-------+
| value |
+-------+
| B     |
+-------+

另一个使用WHERE ... INand 的例子DISTINCT

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

+-------+
| value |
+-------+
| B     |
+-------+
于 2010-07-08T07:22:47.217 回答
39

通过使用 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;

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

于 2013-06-10T14:59:44.167 回答
15

您的查询将始终返回一个空记录集,因为cut_name= '全プロセス' and cut_name='恐慌'永远不会评估为true.

一般来说,INTERSECTinMySQL应该像这样模拟:

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))
        )

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

SELECT  *
FROM    mytable m
WHERE   (col1, col2, col3) IN
        (
        SELECT  col1, col2, col3
        FROM    othertable o
        )
于 2010-04-12T10:58:06.867 回答
5

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

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

在此处输入图像描述

例如:

表1

id, 姓名, jobid

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

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

'3','亚当','2'

'4','比尔','6'

表2

id, 姓名, jobid

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

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

'3','亚当','2'

'4','比尔','5'

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

这是查询:

SELECT * FROM table1 NATURAL JOIN table2;

查询结果: id、name、jobid

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

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

'3','亚当','2'

于 2016-10-24T04:14:12.207 回答
1

为了完整起见,这里是另一种模拟INTERSECT. 请注意,IN (SELECT ...)其他答案中建议的形式通常更有效。

通常对于使用名为mytable的主键调用的表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")

(请注意,如果您使用SELECT *此查询,您将获得两倍于定义的列mytable,这是因为INNER JOIN生成笛卡尔积

这里从您的表中INNER JOIN生成行对的每个排列。这意味着以每个可能的顺序生成每个行组合。然后该WHERE子句过滤该a对的一侧,然后是b一侧。结果是只返回满足两个条件的行,就像两个查询的交集一样。

于 2012-06-08T23:44:11.750 回答
0

用 2 个语句解决您的问题:首先,您要全选 if

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

是真的 。其次,如果你想全选

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

是真的。因此,我们将通过 OR 加入两者,因为如果其中任何一个为真,我们想选择所有。

select * from emovis_reporting
    where (id=3 and cut_name= '全プロセス' and cut_name='恐慌') OR
        ( (id=3) and ( cut_name='全プロセス' or cut_name='恐慌') )
于 2015-06-16T11:39:31.637 回答
-2

AFAIR,MySQL 通过INNER JOIN实现 INTERSECT 。

于 2010-04-12T13:42:17.067 回答
-2
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);
于 2015-05-27T14:21:12.970 回答