在 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"。)
我有 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"。)