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



我有2张桌子母亲和孩子。我想确定它们一起使用多少块。 我通常用来只为一个表确定这一点的代码

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

但由于我需要两个表,并且它们可能使用相同的块,我尝试进行实验。所以我读到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 命令未正确结束" *原因:
*操作: 行错误:18 列:58

查询中有几个错误。

导致立即错误的第一个是关键字AS.在 Oracle 中(与其他数据库产品不同,据我所知),关键字AS对于列别名是可选的,对于表/子查询别名是禁止的。删除别名tem前面的单词AS,该错误已修复。

然后,在外部选择中,您仍然想从dbms_rowid中进行选择 - 但这是不可能的,您已经为子查询提供了别名,因此您只能从中进行选择,而不能从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 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)即可。(也就是说:你确实需要某种形式的"独特",但你只需要一次。要么在外部查询中计数不同,要么像以前一样使用union,而不是在子查询中使用union all,但这样你就不需要在外部查询中使用"不同"。

相关内容

  • 没有找到相关文章