我有一个从我的数据库返回系统和区域的查询,如下所示:
SELECT Areas.ID AreaID,
Areas.Name AreaName,
Systems.*
FROM Systems
INNER JOIN Areas ON Areas.ID = Systems.AreaID
WHERE ....
这将返回如下所示的数据:
| AreaID | AreaName | SystemName | ...
| 1 | area1 | sys1 |
| 1 | area1 | sys2 |
| 1 | area1 | sys3 |
| 1 | area1 | sys4 |
| 2 | area2 | sys5 |
| 2 | area2 | sys6 |
我想返回一个附加列,其中包含返回的每个区域中的系统数量,因此我最终会得到这样的结果:
| AreaID | AreaName | SystemName | noOfSystems | ...
| 1 | area1 | sys1 | 4 |
| 1 | area1 | sys2 | 4 |
| 1 | area1 | sys3 | 4 |
| 1 | area1 | sys4 | 4 |
| 2 | area2 | sys5 | 2 |
| 2 | area2 | sys6 | 2 |
即。有4个系统,区域ID为1和2,区域ID为2。
如何做到这一点?我确信我听说过内置函数可以做到这一点,但我找不到我想要的东西。
答案 0 :(得分:4)
您需要使用聚合函数COUNT()
,然后使用GROUP BY
。这可以在相关子查询中完成:
SELECT Areas.AreaID AreaID,
Areas.areaname AreaName,
s1.SystemName,
(select count(systemname)
from systems s2
where s1.areaid = s2.areaid
group by areaid) noOfSystems
FROM Systems s1
INNER JOIN Areas
ON Areas.AreaID = s1.AreaID
WHERE ....
或者您可以使用您加入的子查询来获取总计数:
SELECT Areas.ID AreaID,
Areas.Name AreaName,
s1.SystemName,
s2.NoOfSystems
FROM Systems s1
INNER JOIN Areas
ON Areas.ID = s1.AreaID
INNER JOIN
(
select COUNT(SystemName) NoOfSystems,
AreaID
from systems
group by AreaID
) s2
on s1.AreaID= s2.AreaID
WHERE ....
此版本使用子查询来获取总计数,然后将其连接回Systems
表以返回其他列(如果需要)。
或者,如果您的RDBMS使用Count() over()
具有此选项,则可以使用窗口函数:
SELECT Areas.ID AreaID,
Areas.Name AreaName,
Systems.SystemName,
COUNT(SystemName) over(partition by Areas.ID, Areas.AreaName) as NoOfSystems
FROM Systems
INNER JOIN Areas
ON Areas.ID = Systems.AreaID
WHERE ....
答案 1 :(得分:1)
使用这样的相关子查询:
SELECT
a.ID AreaID,
a.Name AreaName,
s1.*,
(SELECT COUNT(s2.SystemName)
FROM Systems s2
WHERE a.id = s2.AreasID) AS noofSystem
FROM Systems s1
INNER JOIN Areas a ON a.ID = S1.AreaID
WHERE ....
或强>
SELECT
Areas.ID AreaID,
Areas.Name AreaName,
Systems.SystemName,
COUNT(Systems.SystemName) AS noOfSystems
FROM Systems
INNER JOIN Areas ON Areas.ID = Systems.AreaID
WHERE ...
GROUP BY
Areas.ID AreaID,
Areas.Name AreaName,
Systems.SystemName;
答案 2 :(得分:0)
这将为我们提供结果中的行数,其中AreaID和AreaName与当前行相同。因为我不确定AreaName是否是唯一的,所以我将其包含在计算中:
;WITH cte AS (
-- Original query
SELECT Areas.ID AreaID,
Areas.Name AreaName,
Systems.SystemName
FROM Systems
INNER JOIN Areas ON Areas.ID = Systems.AreaID
--WHERE...
)
SELECT AreaID,
AreaName,
SystemName
-- Here's where we get the count of rows returned for each unique area
(SELECT COUNT(*) FROM cte WHERE AreaID = c.AreaID AND AreaName = c.AreaName) AS noOfSystems
FROM cte c
以这种方式使用common table expression将允许我们使用原始查询而无需更改它。