MySQL 中相交的替代方案
我需要在 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='恐慌') )
我知道 MySQL 中没有 intersect 。所以我需要另一种方式。 请指导我。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
Microsoft SQL Server 的
INTERSECT
"返回由 INTERSECT 操作数左侧和右侧的查询返回的任何不同值” 这与标准INNER JOIN
或WHERE EXISTS
查询。SQL Server
MySQL
对于这个特定的问题,涉及到 id 列,因此不会返回重复的值,但为了完整起见,这里有一个使用
INNER JOIN
和DISTINCT
:另一个使用
WHERE ... IN
和DISTINCT
的示例:Microsoft SQL Server's
INTERSECT
"returns any distinct values that are returned by both the query on the left and right sides of the INTERSECT operand" This is different from a standardINNER JOIN
orWHERE EXISTS
query.SQL Server
MySQL
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
andDISTINCT
:And another example using
WHERE ... IN
andDISTINCT
:有一种更有效的生成相交的方法,即使用 UNION ALL 和 GROUP BY。根据我对大型数据集的测试,性能提高了一倍。
示例:
它更有效,因为使用INNER JOIN解决方案,MySQL将查找第一个查询的结果,然后对于每一行,查找第二个查询的结果。使用 UNION ALL-GROUP BY 解决方案,它将查询第一个查询的结果、第二个查询的结果,然后将结果一次性分组在一起。
There is a more effective way of generating an intersect, by using UNION ALL and GROUP BY. Performances are twice better according to my tests on large datasets.
Example:
It is more effective, because with the INNER JOIN solution, MySQL will look up for the results of the first query, then for each row, look up for the result in the second query. With the UNION ALL-GROUP BY solution, it will query results of the first query, results of the second query, then group the results all together at once.
您的查询将始终返回空记录集,因为
cut_name= '全プロセsu' 和 cut_name='恐慌'
永远不会计算为true
。一般来说,
MySQL
中的INTERSECT
应该像这样模拟:如果您的两个表都有标记为
NOT NULL
的列,则可以省略>IS NULL
部分并使用稍微更高效的IN
重写查询:Your query would always return an empty recordset since
cut_name= '全プロセス' and cut_name='恐慌'
will never evaluate totrue
.In general,
INTERSECT
inMySQL
should be emulated like this:If both your tables have columns marked as
NOT NULL
, you can omit theIS NULL
parts and rewrite the query with a slightly more efficientIN
:我刚刚在 MySQL 5.7 中检查过它,非常惊讶没有人提供一个简单的答案: NATURAL JOIN
当表或(选择结果)具有相同的列时,您可以使用 NATURAL JOIN 作为查找交集的方法:
< /a>
例如:
table1:
id, name, jobid
'1', 'John', '1'
'2', 'Jack', '3'
'3', 'Adam', '2'
'4', 'Bill', '6'
table2:
id, name, jobid
'1', 'John', '1'
'2', 'Jack', '3'
'3', 'Adam', '2'
'4', 'Bill', '5'
'5', 'Max', '6'
以下是查询:
查询结果:
id、姓名、jobid
'1'、'约翰'、'1'
'2'、'杰克'、'3'
'3'、'亚当'、'2'
I just checked it in MySQL 5.7 and am really surprised how no one offered a simple answer: NATURAL JOIN
When the tables or (select outcome) have IDENTICAL columns, you can use NATURAL JOIN as a way to find intersection:
For example:
table1:
id, name, jobid
'1', 'John', '1'
'2', 'Jack', '3'
'3', 'Adam', '2'
'4', 'Bill', '6'
table2:
id, name, jobid
'1', 'John', '1'
'2', 'Jack', '3'
'3', 'Adam', '2'
'4', 'Bill', '5'
'5', 'Max', '6'
And here is the query:
Query Result:
id, name, jobid
'1', 'John', '1'
'2', 'Jack', '3'
'3', 'Adam', '2'
为了完整起见,这里有另一种模拟
INTERSECT
的方法。请注意,其他答案中建议的IN (SELECT ...)
形式通常更有效。通常,对于名为
mytable
且主键名为id
的表:(请注意,如果您在此查询中使用
SELECT *
,您将得到两倍的结果mytable
中定义了许多列,这是因为INNER JOIN
生成 笛卡尔积)这里的
INNER JOIN
生成每个排列。这意味着以每种可能的顺序生成每种行组合。然后,WHERE
子句过滤该对的a
端,然后过滤b
端。结果是仅返回满足两个条件的行,就像交集两个查询所做的那样。For completeness here is another method for emulating
INTERSECT
. Note that theIN (SELECT ...)
form suggested in other answers is generally more efficient.Generally for a table called
mytable
with a primary key calledid
:(Note that if you use
SELECT *
with this query you will get twice as many columns as are defined inmytable
, this is becauseINNER JOIN
generates a Cartesian product)The
INNER JOIN
here generates every permutation of row-pairs from your table. That means every combination of rows is generated, in every possible order. TheWHERE
clause then filters thea
side of the pair, then theb
side. The result is that only rows which satisfy both conditions are returned, just like intersection two queries would do.从 MySQL 8.0.31 开始,原生支持 INTERSECT。
INTERSECT 子句:
样本:
Starting from MySQL 8.0.31 the INTERSECT is natively supported.
INTERSECT Clause:
Sample:
我使用 IN 来制作交集
这是一个用法示例:
这里是转储
I use IN to make Intersection
This is an example of usage:
And here is dump
将您的问题分为两个语句:首先,您要选择所有 if
is true 。其次,您要选择所有 if
为 true 的情况。因此,我们将通过 OR 连接两者,因为如果其中任何一个为真,我们想要选择全部。
Break your problem in 2 statements: firstly, you want to select all if
is true . Secondly, you want to select all if
is true. So, we will join both by OR because we want to select all if anyone of them is true.
通过 INNER JOIN 或 IN() 模拟 INTERSECT 只能用于少数 2-4 个连接集。如果您尝试查找多个集合之间的交互,则需要使用多个 INNER JOIN。但是 MySQL 中的多个 INNER JOIN 绝对是不稳定的解决方案,这可能会导致查询计划执行器的纠缠,在我们的例子中,查询计划执行器会挂起几天,CPU 消耗 100%。
您需要将MySQL更新到版本8.0.31。它包含 INTERSECT 运算符。
Emulation of INTERSECT via INNER JOIN or IN() can only work with few 2-4 joining sets. If you will try to find interaction between multiple sets, you need to use multiple INNER JOINs. But multiple INNER JOINs in MySQL is absolutely unstable solution which may leads entanglement of query plan executor which, in our case, just hang for several days with 100% CPU consumption.
You need to update MySQL to the version 8.0.31. It contains INTERSECT operator.
AFAIR,MySQL 通过 INNER JOIN 实现 INTERSECT。
AFAIR, MySQL implements INTERSECT through INNER JOIN.