【问题标题】:HOW TO USE ORACLE GROUP BY?如何使用 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

有什么想法吗?

【问题讨论】:

    标签: sql oracle group-by


    【解决方案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 在不从子查询中获取数据时显示零值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多