如何使用 ORACLE GROUP BY?

Posted

技术标签:

【中文标题】如何使用 ORACLE GROUP BY?【英文标题】:HOW TO USE ORACLE GROUP BY? 【发布时间】:2021-11-06 17:16:12 【问题描述】:

我尝试用 group by 执行这个选择语句:

SELECT 'WMSALPRO2' AS SERVER,
       0 AS "TOTALSESIONES"
FROM   DUAL
UNION ALL
SELECT 'WMSALPRO1' AS SERVER,
       0 AS "TOTALSESIONES"
FROM   DUAL
UNION ALL 
SELECT SERVER AS SERVER,
       COUNT(*) AS "TOTALSESIONES" 
FROM   (
  SELECT b.sid,
         b.username,
         b.module,
         TRUNC(a.seconds_in_wait/60,2) AS MINUTOS_ESPERA,
         a.event,
         c.object_name,
         b.sql_id,
         d.instance_name AS SERVER 
  FROM   gv$session_wait a,
         gv$session b,
         dba_objects c,
         gv$instance d 
  WHERE  a.event NOT IN (
           'Streams AQ: waiting for messages in the queue',
           'smon timer',
           'pmon timer',
           'rdbms ipc message',
           'SQL*Net message from client',
           'pipe get',
           'null event',
           'SQL*Net message to client'
         ) 
  AND    b.SID = a.SID 
  AND    d.inst_id=a.inst_id 
  AND    username IS NOT NULL 
  AND    C.OBJECT_ID(+) = row_wait_obj# 
  AND    B.STATUS ='ACTIVE'
)
GROUP BY SERVER; 

但在结果中不要按名称分组

SERVER           TOTALSESIONES
---------------- -------------
WMSALPRO2                    0
WMSALPRO1                    0
WMSALPRO2                    4
WMSALPRO1                    8

有什么想法吗?

【问题讨论】:

【参考方案1】:

您可以将查询编写得更简单一些(并使用 ANSI 连接而不是旧的逗号连接):

SELECT COALESE(must_include.server, actual.server) AS server,
       COALESE(actual.TOTALSESIONES, 0) AS TOTALSESIONES
FROM   (
  SELECT 'WMSALPRO2' AS SERVER FROM DUAL
  UNION ALL
  SELECT 'WMSALPRO1' FROM DUAL
) must_include
FULL OUTER JOIN (
  SELECT d.instance_name AS SERVER,
         COUNT(*) AS TOTALSESIONES
  FROM   gv$session_wait a
         INNER JOIN gv$session b
         ON (b.SID = a.SID)
         INNER JOIN gv$instance d
         ON (d.inst_id=a.inst_id)
         RIGHT OUTER JOIN dba_objects c
         ON (C.OBJECT_ID = row_wait_obj#)
  WHERE  a.event NOT IN (
           'Streams AQ: waiting for messages in the queue',
           'smon timer',
           'pmon timer',
           'rdbms ipc message',
           'SQL*Net message from client',
           'pipe get',
           'null event',
           'SQL*Net message to client'
         ) 
  AND    username IS NOT NULL 
  AND    B.STATUS ='ACTIVE'
  GROUP BY SERVER
) actual
ON (must_include.SERVER = actual.SERVER);

【讨论】:

我赞成只是因为它使用了正确的JOIN 语法。为什么有人会赞成使用过时语法的答案?叹息。【参考方案2】:

因为 Group by 不在联合选择范围内。

如果您包含所有语句并将它们分组,就可以了:

    select sub.SERVER, sum(*) from (
SELECT 'WMSALPRO2' AS SERVER, 0 AS "TOTALSESIONES"
  FROM DUAL
UNION ALL
SELECT 'WMSALPRO1' AS SERVER, 0 AS "TOTALSESIONES"
  FROM DUAL
UNION ALL
SELECT SERVER AS SERVER, COUNT(*) AS "TOTALSESIONES"
  FROM (SELECT b.sid,
               b.username,
               b.module,
               TRUNC(a.seconds_in_wait / 60, 2) AS MINUTOS_ESPERA,
               a.event,
               c.object_name,
               b.sql_id,
               d.instance_name AS SERVER
          FROM gv$session_wait a, gv$session b, dba_objects c, gv$instance d
         WHERE a.event NOT IN ('Streams AQ: waiting for messages in the queue',
                               'smon timer',
                               'pmon timer',
                               'rdbms ipc message',
                               'SQL*Net message from client',
                               'pipe get',
                               'null event',
                               'SQL*Net message to client')
           AND b.SID = a.SID
           AND d.inst_id = a.inst_id
           AND username IS NOT NULL
           AND C.OBJECT_ID(+) = row_wait_obj#
           AND B.STATUS = 'ACTIVE')
 GROUP BY SERVER) sub 
 group by SERVER

注意:我没有明白将这些语句放在查询中的逻辑,它们无论如何都是 0:

SELECT 'WMSALPRO2' AS SERVER, 0 AS "TOTALSESIONES"
  FROM DUAL
UNION ALL
SELECT 'WMSALPRO1' AS SERVER, 0 AS "TOTALSESIONES"
  FROM DUAL 

【讨论】:

您不想在外部查询中使用COUNT(*),因为它会计算行数而不是合计行数;你想要 SUMMAX 代替。 谢谢。最后使用 SUM(sub.TotalSessiones) 得到总数。我使用SELECT 'WMSALPRO2' AS SERVER, 0 AS "TOTALSESIONES" FROM DUAL 在不从子查询中获取数据时显示零值

以上是关于如何使用 ORACLE GROUP BY?的主要内容,如果未能解决你的问题,请参考以下文章

如何在以下场景中使用 Oracle Group BY

如何在不使用 GROUP BY 或 PARTITION BY 的情况下对 Oracle SQL 中的数据进行分组

如何解决 Oracle Apex 中的“无法使用 DISTINCT、GROUP BY 等从视图中选择 FOR UPDATE”错误?

如何使用group by 分组查询表中所有字段信息

如何在 Oracle 中编写长 group by/case 子句?

关于C#中group by如何实现多条件分组汇总