Mysql 如何在一个查询中计算1:n关系中两个表中的所有记录?

Mysql 如何在一个查询中计算1:n关系中两个表中的所有记录?,mysql,join,left-join,Mysql,Join,Left Join,我猜这是一个相当简单的问题,但我已经遇到这个问题很多次了,我无法通过搜索(也许我不知道搜索什么)或反复尝试找到解决方案 我有以下表格结构和数据: CREATE TABLE `table_a` ( `id` int(11) NOT NULL auto_increment, `table_b_id` int(11) NOT NULL, `field` varchar(10) NOT NULL, PRIMARY KEY (`id`), KEY `table_b_id` (`tab

我猜这是一个相当简单的问题,但我已经遇到这个问题很多次了,我无法通过搜索(也许我不知道搜索什么)或反复尝试找到解决方案

我有以下表格结构和数据:

CREATE TABLE `table_a` (
  `id` int(11) NOT NULL auto_increment,
  `table_b_id` int(11) NOT NULL,
  `field` varchar(10) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `table_b_id` (`table_b_id`)
);

INSERT INTO `table_a` VALUES(1, 1, 'test 1');
INSERT INTO `table_a` VALUES(2, 1, 'test 2');
INSERT INTO `table_a` VALUES(3, 0, 'test 3');

CREATE TABLE `table_b` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(10) NOT NULL,
  PRIMARY KEY  (`id`)
);

INSERT INTO `table_b` VALUES(1, 'value 1');
INSERT INTO `table_b` VALUES(2, 'value 2');
如您所见,
表b
中的id 2在
表a
中未使用,
表a
中的id 3在
表b\u id
中的值为0。我要做的是检索b中的每个值在
表a
中使用的次数计数,包括
表b
中的2次以及
表b
中未使用的所有值的计数

我提出了以下问题:

SELECT b.name, COUNT(a.id) AS number
FROM table_a AS a
LEFT JOIN table_b AS b ON (b.id = a.table_b_id)
GROUP BY a.table_b_id
但它显然只返回以下内容:

name       number
-----------------
null       1
value 1    2
仅使用SQL如何获取以下内容:

name       number
-----------------
null       1
value 1    2
value 2    0
我正在使用MySQL。我猜答案很简单

编辑:除了联合查询之外,没有其他方法了吗

SELECT b.name, SUM(case when a.id is null then 0 else 1 end) AS number
FROM table_a AS a
RIGHT JOIN table_b AS b ON (b.id = a.table_b_id)
GROUP BY b.id
如果您想要得到空行,这是特别的。我相信你必须把它结合起来

SELECT b.name, SUM(case when a.id is null then 0 else 1 end) AS number 
FROM table_a AS a
RIGHT JOIN table_b AS b ON (b.id = a.table_b_id)
GROUP BY b.id
UNION
select null, count(1) from table_a where table_b_id not in ( select id from table_b )

这个嵌套查询可以使用mysql 5

SELECT b.name, (SELECT COUNT( * ) FROM table_a AS a WHERE a.table_b_id = b.id) AS amount FROM table_b AS b

这里要执行的操作称为
完全外部联接

就目前而言,
MySQL
缺少此功能,这意味着您需要使用
UNION
来模拟is(这并不太糟糕,因为您仍然在单个查询中这样做)


关于解决这个问题的各种方法有一个冗长的讨论。他展示了如何避免使用
联合
,尽管替代机制需要一个额外的“互斥”表,并且他建议这比使用
联合

要慢,这排除了不在表_b(a.id=3)中的一个。呃,您可以将其与左连接的null计数联合,但我不会窃取Jamie的工作。你第一次发布的时候我本想回答这个问题,但后来被删除了,我想,呃,算了吧!对不起,老兄,问题有点不同。我忘了提到我需要两个表中的所有记录,而不仅仅是表b。我不想把它改成基本上告诉每个人他们错了。这不包括表b中没有的那个(a.id=3)。
SELECT  name, SUM(IF(a.id IS NULL, 0, 1))
FROM    table_b b
LEFT JOIN
        table_a a
ON      a.table_b_id = b.id
GROUP BY
        b.id
UNION ALL
SELECT  name, COUNT(*)
FROM    table_a a
LEFT JOIN
        table_b b
ON      b.id = a.table_b_id
WHERE   b.id IS NULL
GROUP BY
        b.id