2

我有一个查询,它从我的数据库中返回系统和区域,如下所示:

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       |

IE 有 4 个系统的 area id 为 1 和 2 的 area id 为 2。

如何才能做到这一点?我确定我听说过这样做的内置函数,但我找不到我想要的。

4

3 回答 3

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 ....

请参阅带有演示的 SQL Fiddle

或者您可以使用您加入的子查询来获取总数:

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 ....

请参阅带有演示的 SQL Fiddle

此版本使用子查询来获取总计数,然后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 ....

请参阅带有演示的 SQL Fiddle

于 2013-02-04T15:20:01.797 回答
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;
于 2013-02-04T15:19:21.750 回答
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

以这种方式使用公共表表达式将允许我们使用原始查询而无需更改它。

于 2013-02-04T15:23:42.807 回答