单列SUM,不是单组组功能

时间:2018-04-03 11:12:12

标签: sql oracle oracle11g

我想知道为什么在这个查询中:

SELECT 100 * (select sum(s.bytes)
                from dba_segments s
                where TABLESPACE_NAME='USERS') / sum(MAXBYTES) used
FROM dba_data_files
WHERE tablespace_name = 'USERS'

我正在

  

不是单组组功能错误

我可以在最后添加GROUP BY tablespace_name来修复它,但我不明白为什么需要它。

还试过将subselect放在MAX中但错误更改为

  

缺少表达

修改

预期结果:0到100之间的1位小数。(4.43725586,结果如下) 我想将2个查询的结果分开,并将其一次性加倍。

获得实际尺寸的第一个查询:

select sum(s.bytes)
from dba_segments s
where TABLESPACE_NAME='USERS'

结果:524091392

获得最大尺寸的第二个查询:

select sum(MAXBYTES)
FROM dba_data_files
WHERE tablespace_name = 'USERS'

结果:1​​.1811E + 10

4 个答案:

答案 0 :(得分:1)

我会在两个派生表之间使用JOIN:

select 100 * (s.used_bytes / df.maxbytes) as used_pct
from (
  select tablespace_name, sum(maxbytes) as maxbytes
  from dba_data_files 
  group by tablespace_name
) df
  join (
    select tablespace_name, sum(bytes) as used_bytes
    from dba_segments 
    group by tablespace_name
  ) s on s.tablespace_name = df.tablespace_name
where s.tablespace_name = 'USERS';

答案 1 :(得分:1)

当使用这样的嵌入式子选择时,Oracle无法理解您是为单个表空间提取数据并且坚持给予GROUP BY

如果您更改查询以使用联接,并使用WHERE子句中指定的表空间名称,则可以避免使用GROUP BY

SELECT 100 * COALESCE(SUM(s.BYTES), SUM(f.BYTES))
         / COALESCE(NULLIF(SUM(f.MAXBYTES), 0), NULLIF(SUM(f.BYTES), 0)) used
  FROM DBA_DATA_FILES f
  LEFT OUTER JOIN DBA_SEGMENTS s
    ON s.TABLESPACE_NAME = f.TABLESPACE_NAME
  WHERE f.TABLESPACE_NAME = 'USERS'

我修改了初始查询以处理SUM(f.MAXBYTES)出现零的问题,它在我的系统上执行,导致“除数为零”错误。

祝你好运。

答案 2 :(得分:1)

我认为这是Oracle中的一个解析错误。以下内容失败并显示相同的消息:

SELECT 100 * (select sum(s.bytes)
              from dba_segments s
             ) / sum(df.MAXBYTES) as used
FROM dba_data_files df
WHERE df.tablespace_name = 'USERS';

然而,这解决了这个问题:

SELECT 100 * (select sum(s.bytes)
                from dba_segments s
                where s.TABLESPACE_NAME = 'USERS'
             ) / sum(df.MAXBYTES) as used
FROM dba_data_files df
WHERE df.tablespace_name = 'USERS'
GROUP BY 'a';  -- a constant here

子查询是不相关的,因此应该被允许。但是,Oracle似乎在没有GROUP BY的版本中禁止它。

至于解决方案,我倾向于将两个子查询移到FROM子句:

SELECT (100 * segment_bytes / df_bytes) as used
FROM (select sum(df.MAXBYTES) as df_bytes
      from dba_data_files df
      where df.TABLESPACE_NAME = 'USERS'
     ) df CROSS JOIN
     (select sum(s.bytes) as segment_bytes
      from dba_segments s
      where s.TABLESPACE_NAME = 'USERS'
     ) s;

答案 3 :(得分:0)

因为您的子选择就像第一列没有聚合结果一样 尝试使用

data.frame