기준과 일치하는 가장 최근 타임스탬프가 있는 행을 선택하는 가장 좋은 방법
이것은 너무 자주 언급되는 것이라 거의 생각을 접을 뻔했지만 저는 이것을 최선의 방법으로 하고 있지 않다고 거의 확신합니다.
질문:다음 표가 있다고 가정합니다.
CREATE TABLE TEST_TABLE
(
ID INTEGER,
TEST_VALUE NUMBER,
UPDATED DATE,
FOREIGN_KEY INTEGER
);
FORINE_KEY = 10인 가장 최근에 업데이트된 행과 관련된 TEST_VALUE를 선택하는 가장 좋은 방법은 무엇입니까?
편집: 아래의 답은 단순히 제 방법으로 정렬한 다음 맨 위 행을 선택하는 것이므로 이 문제를 더 흥미롭게 만들어 보겠습니다.나쁘지는 않지만 대량 반품의 경우에는 성능이 저하될 수 있습니다.따라서 보너스 포인트: 확장 가능한 방식으로 수행하는 방법(즉, 불필요한 주문 없이).
분석 기능은 당신의 친구입니다.
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
첫째, 항상 해당 외래 키로 모든 행을 보고 업데이트된 값이 가장 높은 행을 찾아야 합니다.MAX나 ORDER BY를 의미합니다.비교의 효율성은 부분적으로 Optimizer에 달려 있으므로 Oracle 버전에 따라 달라집니다.데이터 구조가 실제 성능에 더 큰 영향을 미칠 수도 있습니다.FOREAN_KEY, UPDATED 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
)
하지만 오버플로우 천재들을 쌓아두고, 몇 가지 기술을 가르쳐주세요.
테스트 선택_VALUEFROM TEST_TABLEWHERE UPDATED = (최대 선택(업데이트됨)FROM TEST_TABLE여기서 FORINE_KEY = 10 )AND 외국인 키 = 10AND ROWNUM = 1 -- 레코드의 업데이트 날짜가 동일한 경우를 위해
첫 번째 기록을 사용하는 대신 가장 높은 ID 또는 가장 작은/가장 큰 TEST_VALUE로 동점을 만들 수 있습니다.
FORINE_KEY의 인덱스인 UPDATE가 쿼리 성능에 도움이 될 것입니다.
저스틴 케이브의 답변을 읽기 전까지는 다음과 같은 패턴을 사용하여 최근 기록을 대량으로 수집했습니다.
WITH test_table_ranked AS (
SELECT
test_table.*,
ROW_NUMBER() OVER (
PARTITION BY foreign_key ORDER BY updated DESC
) AS most_recent
FROM
test_table
)
SELECT *
FROM test_table_ranked
WHERE most_recent = 1
-- AND foreign_key = 10
이 쿼리는 테이블에서 각 외부 키에 대한 최신 업데이트를 찾습니다.키를 알면 저스틴의 대답이 더 빠르지만, 이 쿼리는 SQL Server에서도 작동합니다.
성능은 색인화된 항목에 따라 달라집니다.여기 방법이 있습니다.
WITH
ten AS
(
SELECT *
FROM TEST_TABLE
WHERE FOREIGH_KEY = 10
)
SELECT TEST_VALUE
FROM ten
WHERE UPDATED =
(
SELECT MAX(DATE)
FROM ten
)
다음과 같은 도움이 되는 Oracle SQL FAQ가 있습니다.
http://www.orafaq.com/wiki/SQL_FAQ
select test_value
from
(
select test_value
from test_table
where foreign_key=10
order by updated desc
)
where rownum = 1
Oracle은 내부 선택 항목에서 하나의 행만 필요로 하며 이를 효율적으로 수행할 수 있다는 것을 충분히 현명하게 인식합니다.
이것은 효과가 있지 않을까요?
SELECT TOP 1 ID
FROM test_table
WHERE FOREIGN_KEY = 10
ORDER BY UPDATED DESC
서브쿼리는 필요없습니다...
언급URL : https://stackoverflow.com/questions/285477/best-way-to-select-the-row-with-the-most-recent-timestamp-that-matches-a-criteri
'programing' 카테고리의 다른 글
libfoo.so .1과 같은 라이브러리 이름이 지정된 전체 파일 경로는 어떻게 찾을 수 있습니까? (0) | 2023.11.01 |
---|---|
날짜 시간을 지원하는 파이썬 JSON 인코더? (0) | 2023.11.01 |
압축-archive 및 상대 경로 보존 (0) | 2023.11.01 |
Mysql 하위 쿼리 결과 "where" 절이 나타납니다. (0) | 2023.11.01 |
-static-libgcc -static-libstdc++를 사용하여 컴파일해도 여전히 libc.so 에 대한 동적 종속성이 발생합니다. (0) | 2023.11.01 |