提问者:小点点

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='恐慌') )

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


共3个答案

匿名用户

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)

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列,因此不会返回重复值,但是为了完整起见,这里有一个使用inner joindistinction的MySQL替代方案:

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

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

以及另一个使用where.。。indistinction的示例:

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

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

匿名用户

使用UNION ALL和GROUP by是生成intersect的一种更有效的方法。 根据我在大型数据集上的测试,性能提高了两倍。

示例:

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;

它更有效,因为有了内部联接解决方案,MySQL会查找第一次查询的结果,然后对于每一行,在第二次查询中查找结果。 使用UNION ALL-GROUP BY解决方案,它将查询第一次查询的结果,第二次查询的结果,然后一次将所有结果分组在一起。

匿名用户

查询将始终返回空记录集,因为cut_name=''且cut_name=''的计算结果永远不会为true

通常,MySQL中的intersect应该这样仿真:

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
        )