在 SQL 中组合 UNION、count(*) 和 rowid,也就是确定 2 个表使用的块

Combining UNION, count(*) and rowid in SQL, aka determine blocks used by 2 tables

我有 2 table 妈妈和 CHILD。我想确定他们一起使用了多少块。 我通常用代码来确定一个 table

select count(count(dbms_rowid.rowid_block_number(rowid))) 
from MOTHER group by dbms_rowid.rowid_block_number(rowid);

但由于我需要两个 table,而且它们可能使用相同的块,所以我尝试了试验。所以我读到 UNION 可能会解决这个问题,但是根据教程我在使用它时遇到了问题

select tem.dbms_rowid.rowid_block_number(rowid), count(*) from
(select dbms_rowid.rowid_block_number(rowid) from MOTHER 
union
select dbms_rowid.rowid_block_number(rowid) from CHILD ) AS tem
group by dbms_rowid.rowid_block_number(rowid);

它不起作用,并在 AS tem 部分显示错误。它说语法错误。 留言:

ORA-00933: SQL 命令未正确结束 00933.00000 - "SQL command not properly ended" *原因:
*行动: 行错误:18 列:58

查询中有几个错误。

导致立即错误的第一个是关键字AS。在Oracle中(与其他数据库产品不同,据我了解)关键字AS对于列别名是可选的,prohibited对于table/subquery别名。删除别名 tem 之前的单词 AS 并且该错误已修复。

然后,在外部 select 你仍然想从 dbms_rowid select - 但这是不可能的,你已经给子查询一个别名,所以你只能select 来自它,而不是来自 union.

的两个分支中引用的表

这是一种更正方法:

select   rowid_block_number, count(*) as cnt    -- DON'T USE THIS QUERY! (SEE BELOW)
from     
         ( 
           select dbms_rowid.rowid_block_number(rowid) as rowid_block_number from MOTHER 
           union
           select dbms_rowid.rowid_block_number(rowid) from CHILD
         )
group by rowid_block_number
;

请注意,我取消了子查询的别名——不需要它。此外,我为应用 rowid_block_number(rowid) 产生的列提供了一个别名 - 你不能像在外部查询中那样调用它。

现在,这在语法上是正确的,但逻辑不存在。对于您的第一次计数,我不知道您为什么分组,并且 select 计数两次。你应该简单地

select count(distinct dbms_rowid.rowid_block_number(rowid)) as block_count
from   MOTHER;

如果您必须对两个不同的表执行此操作:

select count(distinct rowid_block_number) as block_count
from   
       ( 
         select dbms_rowid.rowid_block_number(rowid) as rowid_block_number from MOTHER
         union all
         select dbms_rowid.rowid_block_number(rowid) from CHILD
       )
;

或者,如果您将使用 union 而不是 union all,那将已经消除了重复项,因此只需从子查询中使用 select count(rowid_block_number)。 (也就是说:你确实需要某种形式的 "distinct",但你只需要它一次。要么在外部查询中计算不同,要么像你一样使用 union,而不是 union all ,在子查询中,但是你不需要在外部查询中使用 "distinct"。)