Oracle对表中每一行执行计数

mhd8tkvw  于 2023-01-25  发布在  Oracle
关注(0)|答案(2)|浏览(142)

我对oracle SQL中的查询有疑问。我有一个groups表,可以查询为:

SELECT * 
FROM groups g
WHERE g.owner = 123;

这将给予如下结果:
| 组ID|物主|
| - ------|- ------|
| 1个|一百二十三|
| 第二章|一百二十三|
| 三个|一百二十三|
| 四个|一百二十三|
我还有另一个管理员表,可以查询如下:

SELECT * 
FROM admins a
ORDER BY groupId;

这将使管理员成为:
| 管理ID|用户名|组ID|
| - ------|- ------|- ------|
| 1个|我的管理员1|1个|
| 第二章|我的管理员2|1个|
| 三个|我的管理员3|1个|
| 四个|我的管理员4|第二章|
| 五个|我的管理员5|三个|
| 六个|我的管理员6|三个|
这基本上意味着一个组可以有多个管理员。我想计算每个组的管理员数量。结果如下所示:
| 组ID|物主|管理计数|
| - ------|- ------|- ------|
| 1个|一百二十三|三个|
| 第二章|一百二十三|1个|
| 三个|一百二十三|第二章|
| 四个|一百二十三|无|
但是,我无法对表中的每个管理员进行计数,然后进行连接,因为这是一个包含许多行的表。

SELECT count(*)
FROM admins a
WHERE groupId = 1;

这样,我就可以获得所需的结果,而无需对表中的每个管理员执行计数,只需计算属于特定所有者的组的管理员。
有人知道如何在不计算administrators表中所有行的情况下计算它吗?
谢谢

2q5ifsrm

2q5ifsrm1#

最简单和最可读的变体是使用outer apply(或lateral(+)):

select *
from groups g
     outer apply (
       select count(*) as adminCount
       from admins a
       where a.groupId=g.groupId
     );

或者,您可以使用子查询获得相同的结果(此外,事实上Oracle优化器可以决定将outer-apply/lateral转换为该变体,因为它具有“lateral view decorrelation”转换):

select g.groupId,g.owner, nvl(a.adminCount,0) as adminCount
from groups g
     left join (
         select x.groupId, count(*) as adminCount
         from admins x
         group by x.groupId
     ) a
     on a.groupId=g.groupId;

或者甚至使用join进行group-by:

select g.groupId,g.owner, count(a.groupId) as adminCount
from groups g
     left join admins a
          on g.groupId=a.groupId
group by g.groupId,g.owner

https://dbfiddle.uk/a-Q_abg8

gab6jxml

gab6jxml2#

您可以使用分析函数COUNT()OVER()...

Select  Distinct
        g.GROUP_ID,
        g.OWNER,
        Count(a.ADMIN_ID) OVER(Partition By g.GROUP_ID) "COUNT_ADMINS"
From    groups g
Left Join admins a ON(a.GROUP_ID = g.GROUP_ID)
Where   g.OWNER = 123
Order By g.GROUP_ID

...这需要Distinct关键字,这对于大数据集可能会导致性能成本过高。我不认为用户组和管理员会有那么大。
使用示例数据:

WITH
    groups (GROUP_ID, OWNER) AS
        (
            Select 1, 123 From Dual Union ALL
            Select 2, 123 From Dual Union ALL
            Select 3, 123 From Dual Union ALL
            Select 4, 123 From Dual 
        ),
    admins (ADMIN_ID, ADMIN_USER_NAMAE, GROUP_ID) AS
        (
            Select 1, 'myadmin1', 1 From Dual Union All
            Select 2, 'myadmin2', 1 From Dual Union All
            Select 3, 'myadmin3', 1 From Dual Union All
            Select 4, 'myadmin4', 2 From Dual Union All
            Select 5, 'myadmin5', 3 From Dual Union All
            Select 6, 'myadmin6', 3 From Dual 
        )

...结果是
| 组别编号|业主|管理员计数|
| - ------|- ------|- ------|
| 1个|一百二十三|三个|
| 第二章|一百二十三|1个|
| 三个|一百二十三|第二章|
| 四个|一百二十三|无|

相关问题