Вы можете изменить свой внутренний запрос, чтобы искать другие строки с тем же значением last_receipt
, но другой идентификатор (при условии, что идентификатор уникален); если существует еще одна строка, то это эквивалентно тому, что ваш счет возвращается больше одного. Но вы не можете просто проверить два значения CLOB для равенства, необходимо использовать dbms_lob.compare
:
select ID
from your_table t1
where exists (
select null from your_table t2
where dbms_lob.compare(t2.LATEST_RECEIPT, t1.LATEST_RECEIPT) = 0
and t2.ID != t1.ID
-- or if ID isn't unique: and t2.ROWID != t1.ROWID
);
Применение номер строки фильтра Tricker, так как вы не можете использовать CLOB в аналитическом partition by
пункте. Как предложил Андре Шильд, вы можете использовать хэш; здесь проходит целое значение 3, которое является эквивалентом dbms_crypto.hash_sh1
:
select id from (
select ID, ROW_NUMBER() over (partition by dbms_crypto.hash(LATEST_RECEIPT, 3)
order by ID) rownumber
from your_table t1
where exists (
select null from your_table t2
where dbms_lob.compare(t2.LATEST_RECEIPT, t1.LATEST_RECEIPT) = 0
and t2.ID != t1.ID
-- or if ID isn't unique: and t2.ROWID != t1.ROWID
)
)
where rownumber > 1;
Это, конечно, можно получить хэш столкновения, и если это случилось - (хотя в теории, что может измениться в будущих версиях!) у вас было два значения latest_receipt
, которые оба появились более одного раза и оба хэшируются до одного значения - тогда вы можете получить слишком много строк назад. Это кажется маловероятным, но это нужно учитывать.
Таким образом, вместо заказа вы можете посмотреть только для строк, которые имеют один и тот же lastest_receipt
и нижний ID:
select ID
from your_table t1
where exists (
select null from your_table t2
where dbms_lob.compare(t2.LATEST_RECEIPT, t1.LATEST_RECEIPT) = 0
and t2.ID < t1.ID
);
Опять же, что предполагает идентификатор уникален. Если это не так, вы все равно можете использовать rowid
, но у вас будет меньше контроля над тем, какие строки были найдены - самый низкий rowid
не обязательно самый низкий идентификатор. Предположительно, вы используете это, чтобы обедать строки для удаления. Если вы на самом деле не против какой строке вы держите, и которые вы удаляете, то еще можно было сделать:
and t2.ROWID < t1.ROWID
Но так как вы в настоящее время заказа, что, вероятно, не является приемлемым, и хеширования может быть предпочтительным, несмотря на малый риск.
Какая ошибка возникает? –
ORA00932- несогласованный тип данных - ожидается: получено clob – Vasanthan
Это один из недостатков использования CLOB/BLOB, они не могут использоваться для индексов, а затем также не для функций GROUP BY и других функций agregate. Я думаю, вам придется преобразовать его обратно в тип данных VARCHAR (гораздо больше). –