Объединяя UNION, count(*) и rowid в SQL, он же определяет блоки, используемые двумя таблицами
У меня есть 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
1 ответ
В запросе есть несколько ошибок.
Первым, который вызывает немедленную ошибку, является ключевое слово AS
, В Oracle (отличается от других продуктов баз данных, от того, что я понимаю), ключевое слово AS
необязательно для псевдонимов столбцов и запрещено для псевдонимов таблиц / подзапросов. Удалить слово AS
перед псевдонимом tem
и эта ошибка исправлена.
Затем во внешнем выборе вы все еще хотите выбрать из 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
, в подзапросе, но тогда вам не нужно "отличить" во внешнем запросе.)