【问题标题】:SQL query, how to add count(*) columnSQL查询,如何添加count(*)列
【发布时间】:2013-04-16 12:52:13
【问题描述】:

我有这个问题:

select segment_name,owner,blocks*8192/1024/1024 as MB,tablespace_name
from dba_segments
where segment_name like 'AUD_2%' and owner like 'AUDITOR'
order by 1 desc;

SEGMENT_NAME     OWNER              MB TABLESPACE_NAME
---------------- ---------- ---------- ----------------
AUD_201304       AUDITOR             7 WSS     
AUD_201303       AUDITOR            12 WSS     
AUD_201302       AUDITOR            11 WSS

如何添加 count(*) 列?

我猜一个相关的子查询会做,但究竟如何?

谢谢!

抱歉在stackoverflow上找到了代码,下次最好搜索一下。谢谢

抱歉,这里是解决方案的链接: How to count(*) of multiple tables, size and tablespace in one query

这里是代码:

SELECT ut.table_name,
           to_number(extractvalue(xmltype (dbms_xmlgen.getxml ('select count(*) c from '         ||ut.table_name)),'/ROWSET/ROW/C')) row_count,
       db.blocks*8192/1024/1024 as MB,
       db.tablespace_name
FROM user_tables ut
  join dba_segments db on db.segment_name = ut.table_name
WHERE ut.table_name LIKE 'AUD_2%' and owner like 'AUDITOR'
ORDER BY ut.table_name DESC;

这里是输出:

TABLE_NAME                      ROW_COUNT         MB TABLES
------------------------------ ---------- ---------- ------
AUD_201304                          21067          7 WSS
AUD_201303                          43198         12 WSS
AUD_201302                          39046         11 WSS
AUD_201301                          44523         17 WSS
AUD_201212                          50580         15 WSS
AUD_201211                          49589         14 WSS

【问题讨论】:

  • 你使用的是什么关系型数据库??
  • @MahmoudGamal:由于查询中的dba_segments,我猜测它是Oracle。
  • 你到底要数什么?
  • 如果您找到了解决方案,那么至少有礼貌地链接到它并将这个问题标记为已回答(或关闭为重复)

标签: sql oracle count subquery


【解决方案1】:

试试:

select 
        segment_name,
        owner,
        blocks*8192/1024/1024 as MB,
        tablespace_name,
        (select num_rows from dba_tables where table_name=segment_name) TOTAL_ROWS
from dba_segments
where segment_name like 'AUD_2%' and owner like 'AUDITOR'
order by 1 desc;

【讨论】:

  • 对不起,这不起作用,给出的列是表的数量,而不是每个表中的记录数
【解决方案2】:

您可以在查询结束时检索@@ROW_COUNT

【讨论】:

  • 在 Oracle 中你不能
  • 我虽然这是一个 SQL Server 问题...那么,M$ @@ROW_COUNT 的 Oracle 对应项是什么?
  • @@ROW_COUNT 相当于 Oracle 的 SQL%ROWCOUNT。我的 MSSQL 有点生疏,但我认为您不能按照您建议的方式在查询中使用 @@ROW_COUNT。当然 SQL%ROWCOUNT 只返回受前一个 DML 语句影响的行数(即更新、删除等的行数)。
【解决方案3】:

不清楚你想计算什么。但是如果你想计算返回的行数,那么使用解析函数:

select segment_name, owner, blocks*8192/1024/1024 as MB, tablespace_name,
       count(*) over () as cnt
from dba_segments
where segment_name like 'AUD_2%' and owner like 'AUDITOR'
order by 1 desc;

【讨论】:

    【解决方案4】:

    "给出的列是表的数量,而不是每个表中的记录数"

    您正在混合两个不同的概念。数据和元数据。

    您的查询是查询数据字典以获取有关您的表的一些信息作为数据库中的对象。这是元数据:关于数据的数据。

    而每个表包含多少行的计数只是数据。

    你有两个选择。第一个是将 DBA_TABLES 视图加入您的查询并选择 NUM_ROWS。如果您的统计数据相当新鲜,并且您只需要一个指示性数字,这可能就足够了。

    如果您不对这些表使用统计信息,或者您想要高度准确的计数,则需要使用 PL/SQL。

    create or replace function tab_row_cnt ( tname in user_tables.table_Nmae%type)
    return pls_integer
    is
      n pls_integer;
    begin
      execute immediate 'select count(*) from '||tname into n;
      return n;
    end;
    

    您可以将此函数包含在查询的投影中。

    select segment_name,owner,blocks*8192/1024/1024 as MB,tablespace_name
           , tab_row_cnt (segment_name) as row_count
    from dba_segments
    where segment_name like 'AUD_2%' and owner like 'AUDITOR'
    and segment_type = 'TABLE'
    order by 1 desc;
    

    请注意,我在 SEGMENT_TYPE 上添加了一个测试。如果您的表是分区的,或者您想在查询中包含索引段,则需要修改函数的逻辑。

    请注意,如果您的表很大,计数可能会花费很长时间,并且会大大减慢您的查询速度。速度是使用 USER_TABLES.NUM_ROWS 提供的近似值的另一个优势。

    【讨论】:

      猜你喜欢
      • 2014-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      • 2012-12-26
      • 2011-12-11
      相关资源
      最近更新 更多