如何在单个查询中计算与基表结果匹配的多个表的记录?
Posted
技术标签:
【中文标题】如何在单个查询中计算与基表结果匹配的多个表的记录?【英文标题】:How to count records of multiple tables that match the results of a base table in a single query? 【发布时间】:2018-07-05 10:12:51 【问题描述】:下面的查询返回所有procedures表的名称和table1中匹配结果的个数,如下:
SELECT p.name, COUNT(t1.id) as Quantity
FROM procedures p
LEFT JOIN table1 t1
ON p.id = t1.id
GROUP BY p.name ASC
如何进行上面的查询,但要计算许多其他表?想象一下,我还有 2 个表要计数,查询输出如下所示的列:
Name Quantity1 Quantity2 Quantity3
A 0 100 27
B 10 0 15
C 50 200 1
程序表:
id name
1 A
2 B
3 C
我想根据过程统计匹配结果的其他表
table1、table2、table3...
id name
1 A
1 A
1 A
2 B
2 B
3 C
3 C
【问题讨论】:
样本数据和期望的结果会有所帮助。重复使这变得棘手。 我放了一些示例数据以使其更易于理解。 【参考方案1】:也加入其他表:
SELECT p.name,
COUNT(t1.id) as Quantity1,
COUNT(t2.id) as Quantity2,
COUNT(t3.id) as Quantity3
FROM procedures p
LEFT JOIN table1 t1 ON p.id = t1.id
LEFT JOIN table2 t2 ON p.id = t2.id
LEFT JOIN table3 t3 ON p.id = t3.id
GROUP BY p.name ASC
【讨论】:
我尝试了您的解决方案,显示已按我的意愿完成,但计数值很奇怪,看起来一列正在影响其他列的计数,例如: Quantity1 的过程 A 等于20,这个值是正确的,但是在 Quantity 2 相同的过程 A 应该等于 5,出现为 20,重复 Quantity2 的相同值。您是否知道如何单独进行所有这些计数,而不会在列之间产生任何干扰?【参考方案2】:最好的办法大概是在join
之前聚合:
SELECT p.name, SUM(t1.cnt1) as cnt1
FROM procedures p LEFT JOIN
(SELECT t1.id, COUNT(*) as cnt1
FROM table1 t1
GROUP BY t1.id
) t1
ON p.id = t1.id
GROUP BY p.name ASC;
嗯,如果 name
和 id
不是 1-1,你仍然会得到重复。如果这是一个问题,那么:
SELECT p.name, t1.cnt1 as cnt1
FROM (SELECT DISTINCT name
FROM procedures p
) p LEFT JOIN
(SELECT p.name, COUNT(*) as cnt1
FROM table1 t1 JOIN
procedures p
ON p.id = t1.id
GROUP BY p.name
) t1
ON p.name = t1.name;
这种方法可以安全地泛化。
【讨论】:
以上是关于如何在单个查询中计算与基表结果匹配的多个表的记录?的主要内容,如果未能解决你的问题,请参考以下文章