На самом деле поведение очень хорошо задокументировано :
Для операторов
BLOCKQUOTE>REPLACE
значение затрагиваемых строк равно 2, если новая строка заменяет старую строку, поскольку В этом случае одна строка была вставлена после удаления дубликата.
Аналитические функции являются Вашими друзьями
SQL> select * from test_table;
ID TEST_VALUE UPDATED FOREIGN_KEY
---------- ---------- --------- -----------
1 10 12-NOV-08 10
2 20 11-NOV-08 10
SQL> ed
Wrote file afiedt.buf
1* select * from test_table
SQL> ed
Wrote file afiedt.buf
1 select max( test_value ) keep (dense_rank last order by updated)
2 from test_table
3* where foreign_key = 10
SQL> /
MAX(TEST_VALUE)KEEP(DENSE_RANKLASTORDERBYUPDATED)
-------------------------------------------------
10
Можно также расширить это для получения информации для всей строки
SQL> ed
Wrote file afiedt.buf
1 select max( id ) keep (dense_rank last order by updated) id,
2 max( test_value ) keep (dense_rank last order by updated) test_value
,
3 max( updated) keep (dense_rank last order by updated) updated
4 from test_table
5* where foreign_key = 10
SQL> /
ID TEST_VALUE UPDATED
---------- ---------- ---------
1 10 12-NOV-08
И аналитические подходы обычно симпатичны, чинил эффективный.
Я должен также указать, что аналитические функции являются относительно новыми, поэтому если Вы находитесь на чем-то ранее, чем 9.0.1, это не может работать. Это больше не огромное население, но всегда существует несколько человек, застрявших на старых версиях.
Любое использование подзапрос
WHERE updated = (SELECT MAX(updated) ...)
или выберите запись TOP 1 с
ORDER BY updated DESC
В синтаксисе Oracle это было бы:
SELECT
*
FROM
(
SELECT * FROM test_table
ORDER BY updated DESC
)
WHERE
ROWNUM = 1
Во-первых, необходимо будет всегда смотреть на все строки с тем внешним ключом и находить тот с самым высоким ОБНОВЛЕННЫМ значением..., что означает МАКСА или ORDER BY. Эффективность сравнения частично до оптимизатора, так будет зависеть от Вашей версии Oracle. Ваши структуры данных могут оказать большее влияние на фактическую производительность все же. Индекс на FOREIGN_KEY, ОБНОВЛЕННОМ DESC, TEST_VALUE, вероятно, дал бы большую часть масштабируемого решения для запросов, поскольку Oracle будет обычно мочь дать ответ, просто получающий доступ к единственному листовому блоку. Может быть вредное влияние на вставки, поскольку новые записи должны быть вставлены в ту структуру.
Вероятно, нижний путь, которым я в настоящее время иду о выполнении чего-то вроде этого,
SELECT TEST_VALUE
FROM TEST_TABLE
WHERE ID = (
SELECT ID
FROM (
SELECT ID
FROM TEST_TABLE
WHERE FOREIGN_KEY = 10
ORDER BY UPDATED DESC
)
WHERE ROWNUM = 1
)
но Гении StackOverflow, преподавайте мне некоторые приемы
SELECT TEST_VALUE FROM TEST_TABLE WHERE UPDATED = ( SELECT MAX(UPDATED) FROM TEST_TABLE WHERE FOREIGN_KEY = 10 ) AND FOREIGN-KEY = 10 AND ROWNUM = 1 -- Just in case records have the same UPDATED date
Скорее то взятие первая запись Вы могли повредить связь с самым высоким идентификатором или возможно наименьшим количеством/самым большим TEST_VALUE.
Индекс FOREIGN_KEY, ОБНОВЛЕННОГО, помог бы запросить производительность.
Производительность будет зависеть от того, что индексируется. Вот метод.
WITH
ten AS
(
SELECT *
FROM TEST_TABLE
WHERE FOREIGH_KEY = 10
)
SELECT TEST_VALUE
FROM ten
WHERE UPDATED =
(
SELECT MAX(DATE)
FROM ten
)
не был бы эта работа:
SELECT TOP 1 ID
FROM test_table
WHERE FOREIGN_KEY = 10
ORDER BY UPDATED DESC
никакая потребность в подзапросе...
select test_value
from
(
select test_value
from test_table
where foreign_key=10
order by updated desc
)
where rownum = 1
Oracle достаточно умна, чтобы понять, что ей только нужна одна строка от внутреннего выбора, и она сделает это эффективно.
Существует оракул часто задаваемые вопросы SQL здесь, которые могут помочь Вам: