2

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

我有以下表结构和数据:

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');

如您所见, id 2 intable_b未使用 intable_a并且 id 3 intable_a的值为 0 table_b_id。我想要做的是检索 b 中每个值在 中使用的次数的计数table_a,包括 2 fromtable_b和所有不在中的值的计数table_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。我猜答案很简单。

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

4

4 回答 4

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 )
于 2009-04-02T03:16:22.850 回答
1

你想在这里做的事情叫做FULL OUTER JOIN.

就目前而言,MySQL缺少此功能,这意味着您需要使用 a 来模拟 is UNION(这还不错,因为您仍然在单个查询中执行此操作)。

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
于 2009-04-02T13:11:54.697 回答
0

Xaprb在这篇文章中对解决此问题的各种方法进行了冗长的讨论。他展示了如何避免使用 a UNION,尽管替代机制需要一个额外的“互斥”表,并且他建议它比使用UNION.

于 2009-04-05T08:54:44.643 回答
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
于 2009-04-02T13:01:45.343 回答