我猜这是一个相当简单的问题,但我已经多次遇到这个问题,我无法通过搜索找到解决方案(也许我不知道要搜索什么)或试用和错误。
我有以下表结构和数据:
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');
如您所见,table_b
中的ID 2未在table_a
中使用,table_a
中的ID 3在table_b_id
中的值为0。我想要做的是检索table_a
中使用b中每个值的次数,包括来自table_b
的2和所有不在table_b
中的值的计数。< / p>
我提出了以下问题:
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。我猜测答案很简单。
编辑:除了union'd查询之外,还有其他方法吗?
答案 0 :(得分:1)
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 )
答案 1 :(得分:1)
您要在此处执行的操作称为FULL OUTER JOIN
。
就目前而言,MySQL
缺少此功能,这意味着您需要使用UNION
进行模拟(这在单个查询中仍然可以实现)。< / p>
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
答案 2 :(得分:0)
这个嵌套查询适用于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
答案 3 :(得分:0)
关于this post by Xaprb解决这个问题的各种方法,有一个冗长的讨论。他展示了如何避免使用UNION
,尽管替代机制需要额外的“互斥”表,他认为它比使用UNION
要慢。