计算不同表中的行并按特定条件分组
Counting rows in different tables and grouping by a certain criteria
我有 3 个表:项目、组件、供应商。每个都有一个 id 列、city 列和一些其他列。
我想做的是计算每个城市有多少个项目、组件和供应商。
我试过的是:
SELECT p.city, COUNT(p.idp), COUNT(c.idc), COUNT(s.idf) FROM
Projects p, Components c, Suppliers s
GROUP BY p.city
在 运行 这个查询之后,我得到了不正确的值,几乎所有值都是相同的,如下所示:
我只为每个城市存储了一个项目、1 或 2 个组件和 1-3 个供应商,所以这些不是预期的结果
在寻找一些类似的已解决问题后,我想出了这段代码
SELECT p.city , p.nr_projects, c.nr_components, s.nr_suppliers
FROM
(SELECT city, COUNT(idp) AS nr_projects
FROM Projects
GROUP BY city)
AS p
JOIN
(SELECT city, COUNT(idc) AS nr_components
FROM Components
GROUP BY city)
AS c
ON p.city=c.city
JOIN
(SELECT city, COUNT(idf) AS nr_suppliers
FROM Suppliers
GROUP BY city)
as f
ON p.city=f.city
GROUP BY p.city;
这给了我一个错误,说 SQL 命令没有正确结束。
我应该如何处理这个任务?
由于您不再在查询的顶层执行任何聚合,因此您不再需要 GROUP BY
子句。此外,对于 Oracle,您不能在 table 别名表达式中使用 AS
。这应该有效:
SELECT p.city , p.nr_projects, c.nr_components, s.nr_suppliers
FROM
(SELECT city, COUNT(*) AS nr_projects
FROM Projects
GROUP BY city) p
JOIN
(SELECT city, COUNT(*) AS nr_components
FROM Components
GROUP BY city) c ON p.city=c.city
JOIN
(SELECT city, COUNT(*) AS nr_suppliers
FROM Suppliers
GROUP BY city) s ON p.city=s.city
请注意,如果一个城市可能没有项目、组件或供应商,那么您应该使用 FULL OUTER JOIN
代替 JOIN
以确保您仍然在输出中获得该城市的行。
另请注意,使用 COUNT(*)
比计算特定变量更有效(因为不需要检查 NULL
值)并且我已对查询进行了修改.
合并总数,然后合计。
这样,您还可以获得其中 1 个表格中缺失的城市的总数。
使用 INNER JOIN
时不会出现在结果中。 (但他们会 FULL JOIN
)
SELECT city,
SUM(proj) AS projects,
SUM(comp) AS components,
SUM(supp) AS suppliers
FROM
(
SELECT city
, COUNT(idp) AS proj
, 0 AS comp
, 0 AS supp
FROM Projects
GROUP BY city
UNION ALL
SELECT city, 0, COUNT(idc), 0
FROM Components
GROUP BY city
UNION ALL
SELECT city, 0, 0, COUNT(idf)
FROM Suppliers
GROUP BY city
) q
GROUP BY city
ORDER BY city
我有 3 个表:项目、组件、供应商。每个都有一个 id 列、city 列和一些其他列。
我想做的是计算每个城市有多少个项目、组件和供应商。
我试过的是:
SELECT p.city, COUNT(p.idp), COUNT(c.idc), COUNT(s.idf) FROM
Projects p, Components c, Suppliers s
GROUP BY p.city
在 运行 这个查询之后,我得到了不正确的值,几乎所有值都是相同的,如下所示:
我只为每个城市存储了一个项目、1 或 2 个组件和 1-3 个供应商,所以这些不是预期的结果
在寻找一些类似的已解决问题后,我想出了这段代码
SELECT p.city , p.nr_projects, c.nr_components, s.nr_suppliers
FROM
(SELECT city, COUNT(idp) AS nr_projects
FROM Projects
GROUP BY city)
AS p
JOIN
(SELECT city, COUNT(idc) AS nr_components
FROM Components
GROUP BY city)
AS c
ON p.city=c.city
JOIN
(SELECT city, COUNT(idf) AS nr_suppliers
FROM Suppliers
GROUP BY city)
as f
ON p.city=f.city
GROUP BY p.city;
这给了我一个错误,说 SQL 命令没有正确结束。
我应该如何处理这个任务?
由于您不再在查询的顶层执行任何聚合,因此您不再需要 GROUP BY
子句。此外,对于 Oracle,您不能在 table 别名表达式中使用 AS
。这应该有效:
SELECT p.city , p.nr_projects, c.nr_components, s.nr_suppliers
FROM
(SELECT city, COUNT(*) AS nr_projects
FROM Projects
GROUP BY city) p
JOIN
(SELECT city, COUNT(*) AS nr_components
FROM Components
GROUP BY city) c ON p.city=c.city
JOIN
(SELECT city, COUNT(*) AS nr_suppliers
FROM Suppliers
GROUP BY city) s ON p.city=s.city
请注意,如果一个城市可能没有项目、组件或供应商,那么您应该使用 FULL OUTER JOIN
代替 JOIN
以确保您仍然在输出中获得该城市的行。
另请注意,使用 COUNT(*)
比计算特定变量更有效(因为不需要检查 NULL
值)并且我已对查询进行了修改.
合并总数,然后合计。
这样,您还可以获得其中 1 个表格中缺失的城市的总数。
使用 INNER JOIN
时不会出现在结果中。 (但他们会 FULL JOIN
)
SELECT city,
SUM(proj) AS projects,
SUM(comp) AS components,
SUM(supp) AS suppliers
FROM
(
SELECT city
, COUNT(idp) AS proj
, 0 AS comp
, 0 AS supp
FROM Projects
GROUP BY city
UNION ALL
SELECT city, 0, COUNT(idc), 0
FROM Components
GROUP BY city
UNION ALL
SELECT city, 0, 0, COUNT(idf)
FROM Suppliers
GROUP BY city
) q
GROUP BY city
ORDER BY city