mySQL 中的完全外连接计数
Posted
技术标签:
【中文标题】mySQL 中的完全外连接计数【英文标题】:Count of full outer join in mySQL 【发布时间】:2018-09-07 18:52:30 【问题描述】:我正在尝试显示完整外连接表中的总行数。我有以下代码,但 mysql 说重复列有错误。这 2 个表(演员和导演)具有相同的列,因为它们应该在各自的类别中提供类似的信息。
SELECT COUNT(*) FROM
(SELECT * FROM directors LEFT OUTER JOIN actors
ON directors.name = actors.name
UNION
SELECT * FROM directors RIGHT OUTER JOIN actors
ON directors.name = actors.name) AS table1;
如何修复代码以使其正常运行?仅供参考,括号内的代码运行良好。只有在我输入 SELECT COUNT(*) 子句后才会出现问题。
【问题讨论】:
来自 MySQL 的确切错误消息是什么? 【参考方案1】:因为有两个name
列,一个来自directors
表,另一个来自actors
表,而你select *
会让DB 引擎混淆你想要获取哪个名称。
如果你只想count
总数你可以试试这个。
SELECT COUNT(*) FROM
(
SELECT directors.name FROM directors LEFT OUTER JOIN actors
ON directors.name = actors.name
UNION
SELECT directors.name FROM directors RIGHT OUTER JOIN actors
ON directors.name = actors.name
) table1;
注意
我建议使用select
清除列并避免使用select *
【讨论】:
数据库中可能只有两个名字和数百条记录。 百万数据在OP中没有提到,这个OP的问题是如何解决错误。 啊,我现在明白你的意思了,在不知道其余列的情况下,你只能说名字;我更关心的是“bob”可能会在其他列中出现多次,而其他列中的数据不同,这会将所有“bob”记录合并为一个。【参考方案2】:最好将右连接部分更改为非冗余,然后添加单独的 很重要。
通用版:
SELECT (SELECT COUNT(*) FROM A LEFT JOIN B ON A.x = B.x)
+ (SELECT COUNT(*) FROM B LEFT JOIN A ON B.x = A.x WHERE A.x IS NULL)
AS outerJoinSize
;
注意:我将 RIGHT JOIN 更改为 LEFT JOIN 并交换了表格;根据我的经验,RIGHT JOIN 只会使查询更难阅读(尤其是在涉及多个联接时)。
一个完全不同的选择......
SELECT
( SELECT SUM(dc1.c * IFNULL(ac1.c, 1)) AS jc
FROM (SELECT name, COUNT(*) AS c FROM directors GROUP BY name) AS dc1
LEFT JOIN (SELECT name, COUNT(*) AS c FROM actors GROUP BY name) AS ac1
ON dc1.name = ac1.name)
+ (SELECT SUM(IF(dc2.name IS NULL, ac2.c, 0)) AS jc
FROM (SELECT name, COUNT(*) AS c FROM actors GROUP BY name) AS ac2
LEFT JOIN (SELECT name, COUNT(*) AS c FROM directors GROUP BY name) AS dc2
ON ac2.name = dc2.name)
...根据加入字段计算出有多少匹配项(导演中的 3 个“Bob”实例和演员中的 2 个实例意味着该名称的 6 个加入结果)。
【讨论】:
您的计数不等于 UNION 的计数,请参阅此小提琴sqlfiddle.com/#!9/b538c5/5 我得看看,但我正试图获得交叉连接的计数; UNION [DISTINCT] 不一定可以复制。 我计算出的 outerJoinSize 根据我在脑海中用该数据计算出来的交叉连接看起来是正确的;小提琴中的当前 UNION ALL 无法得出相同的答案,因为联合的第二个查询需要使用WHERE a.x IS NULL
消除第一个查询中的重复项【参考方案3】:
我不确定您对full join
的了解。但是在 MySQL 中实现它的最佳方式是使用两个left join
s 和一个union
:
select count(*)
from ((select name from directors) union -- on purpose
(select name from actors)
) da left join
directors d
on da.name = d.name left join
actors a
on da.name = a.name;
但是,如果我不得不猜测,您只需要两个表之间不同名称的数量。如果是这样:
select count(*)
from ((select name from directors) union -- on purpose
(select name from actors)
) da
【讨论】:
以上是关于mySQL 中的完全外连接计数的主要内容,如果未能解决你的问题,请参考以下文章