2014-10-17 1 views
0

레코드가 물리적으로 업데이트되지 않지만 새로운 레코드를 추가하여 논리적으로 업데이트되는 "삽입 전용" CRUD 값으로 더 큰 시퀀스를 전달합니다. 이 경우 "seq"(시퀀스) 열은 기본 키로 간주 할 수있는 내용에 더 가깝지만 "id"는 레코드의 논리적 식별자입니다.하나의 열에 최대 값을 갖는 테이블의 행에 대한 논리 테이블을 나타내는 CTE

 
seq id name | CRUD | 
----|-----|--------|------| 
2 | 10 | joe | U | 
3 | 11 | kent | C | 
5 | 12 | sue | U | 
6 | 13 | jill | C | 
7 | 14 | bill | C | 

에서 :

 
seq id name | CRUD | 
----|-----|--------|------| 
1 | 10 | john | C | 
2 | 10 | joe | U | 
3 | 11 | kent | C | 
4 | 12 | katie | C | 
5 | 12 | sue | U | 
6 | 13 | jill | C | 
7 | 14 | bill | C | 

이 테이블의 논리적 표현은 "가장 최근의"기록을 고려한다 : 예 아래에서

이 테이블의 물리적 표현입니다 예를 들어 id = 12 인 사람의 가장 최근 레코드를 검색하려면 다음과 같이하십시오.

SELECT 
    * 
FROM 
    PEOPLE P 
WHERE  
    P.ID = 12 
AND 
    P.SEQ = (
     SELECT 
      MAX(P1.SEQ) 
     FROM 
      PEOPLE P1 
     WHERE P.ID = 12 
    ) 

... 그리고 나는이 행받을 것이다 :

WITH 
    NEW_P 
AS 
(
    --CTE representing all of the most recent records 
    --i.e. for any given id, the most recent sequence 
) 

SELECT 
    * 
FROM 
    NEW_P P2 
WHERE  
    P2.ID = 12 

이미 서브 쿼리를 사용하여 첫 번째 SQL의 예를 우리를 위해 작동합니다

 
seq id name | CRUD | 
----|-----|--------|------| 
5 | 12 | sue | U | 

내가 대신 할 거라고하는 것은이 같은입니다.

질문 : 질문 : 테이블의 "가장 최근"의 논리적보기를 활용해야 할 때 술어를 단순화하기 위해 어떻게 CTE를 활용할 수 있습니까? 본질적으로, 나는 가장 최근의 레코드를 얻고 싶을 때마다 하위 쿼리를 인라인 할 필요가 없습니다. 차라리 CTE를 정의하고 후속 술어에서이를 활용할 것입니다.

P. 현재 DB2를 사용하고 있지만 데이터베이스에 무관 한 솔루션을 찾고 있습니다.

+0

질문이 무엇인지 잘 모릅니다. 데이터 모델은 확장 성이없는 것 같습니다. 전체 테이블 크기와 각 ID에 대한 레코드 수가 증가함에 따라 어떤 레코드가 최신 레코드인지 파악하는 데 더 많은 시간을 할애 할 것입니다.어떤 레코드가 활성 (최신)인지 보여주는 플래그를 저장할 지표 열을 추가하는 것이 좋습니다. – mustaccio

+0

@ mustaccio, 조언을 주셔서 감사합니다. '삽입 전용'패러다임이 사용되는 다른 비즈니스 이유가 있습니다. 이것이 영향을 받거나 변경 될 수는 있지만 데이터 모델이 그대로 있다고 가정 할 때 원래의 질문은 다루지 않습니다. – sparty02

+0

내가 말했듯이, 나는 당신의 질문이 무엇인지 모른다. "생각들?" -- 그게 다야? 표시기 열을 추가해도 "삽입 만하는 패러다임"은 변경되지 않지만 테이블을 더 쉽고 빠르게 쿼리 할 수 ​​있습니다. – mustaccio

답변

1

현대의 모든 SQL 데이터베이스에서 지원되는 (또는 OLAP) 함수의 경우는 분명합니다. 예 :

WITH 
    ORD_P 
AS 
(
    SELECT p.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY seq DESC) rn 
    FROM people p 
) 
, 
    NEW_P 
AS 
(
    SELECT * from ORD_P 
    WHERE rn = 1 
) 
SELECT 
    * 
FROM 
    NEW_P P2 
WHERE  
    P2.ID = 12 

ps. 검증되지 않은. CTE 절의 모든 열을 명시 적으로 나열해야 할 수도 있습니다.

+0

최종 결과는 정확히 제가 찾고있는 것입니다!이 접근 방식에 대한 정보를 추가해 보겠습니다. 비슷한 접근 방식과 @ Glenn의 대답을 기반으로 표시합니다. 대답 : – sparty02

+0

나는 두 글자의 CTE를 사용하는 @ Glenn의 대답에서 영감을 얻은 답변을 포함 시켰습니다. 본질적으로 이미 ID로 최신 시퀀스를 표현한 후에 자체 조인을합니다. 성능에 대한 생각은 무엇입니까? 차이점)? 나는 윈도우 함수에서 매우 녹색이다. (그러나 배우기를 좋아할 것이다.) – sparty02

+0

윈도우 함수는 일반적으로 집계보다 성능이 뛰어나다. 특히 후자가 결합과 결합되었을 때 더욱 그렇다. r, 실제 시스템에서 실제 데이터로 테스트하지 않으면 성능에 대한 추측은 쓸모가 없습니다. – mustaccio

1

이미 정리해 놓았습니다. 먼저 기본 테이블에 다시 가입이를 사용하여 다음 각 id와 관련된 최대 seq을 찾을 : 원래 일하는 것이 있었다, 또는 "에서"절에 CTE를 이동 무엇

WITH newp AS (
    SELECT id, MAX(seq) AS latestseq 
    FROM people 
    GROUP BY id 
) 
SELECT p.* 
    FROM people p 
    JOIN newp n ON (n.latestseq = p.seq) 
    ORDER BY p.id 

. 어쩌면 순서에 시퀀스 번호가 아닌 타임 스탬프 필드를 사용하고 싶습니까?

+0

@ mustaccio의 답변은 내가 찾고있는 것에 더 가깝습니다 (사용하려고 할 때마다 그 CTE에 다시 가입하지 않아도됩니다.) 아래에 대체 답변을 포함 시켰지만 당신이 가지고있는 것에 영감을 얻었지만 어떤 프로/두 접근법 사이의 단점은 "최상의"것을 선택하는 것입니다. – sparty02

0

@ Glenn의 답변을 보면, 원래 목표를 달성하고 @ mustaccio의 대답과 동등한 업데이트 된 쿼리가 있지만이 방법의 성능 및 기타 영향이 무엇인지 아직 확실하지 않습니다. 다른 사람은.

WITH 
    LATEST_PERSON_SEQS AS 
    (
     SELECT 
      ID, 
      MAX(SEQ) AS LATEST_SEQ 
     FROM 
      PERSON 
     GROUP BY 
      ID 
    ) 
    , 
    LATEST_PERSON AS 
    (
     SELECT 
      P.* 
     FROM 
      PERSON P 
     JOIN 
      LATEST_PERSON_SEQS L 
     ON 
      (
       L.LATEST_SEQ = P.SEQ) 
    ) 
SELECT 
    * 
FROM 
    LATEST_PERSON L2 
WHERE 
    L2.ID = 12