2008-08-24 2 views
4

사용자 테이블 (userid, firstname, lastname) 및 usermetadata 테이블 (userid, code, content, created datetime)이있는 postgres 데이터베이스가 있습니다. usermetadata 테이블에 각 사용자에 대한 다양한 정보를 코드로 저장하고 전체 기록을 유지합니다. 내 모든 사용자의 목록과 다양한 usermetadata 코드의 각각의 가장 최근의 값을 가져 오기 위해 필요사용자 행에 다양한 usermetadata 태그를 최신으로 연결합니다.

15, 'QHS', '20', '2008-08-24 13:36:33.465567-04' 
15, 'QHE', '8', '2008-08-24 12:07:08.660519-04' 
15, 'QHS', '21', '2008-08-24 09:44:44.39354-04' 
15, 'QHE', '10', '2008-08-24 08:47:57.672058-04' 

: 그래서 예를 들어, 사용자 (아이디 15)는 다음과 같은 메타 데이터를 가지고있다. 나는 이것을 프로그램 적으로 수행했으며 물론 천재적이었다. SQL에서이 작업을 수행 할 수있는 최선의 방법은 하위 선택 항목에 참여하는 것이 었습니다. 하위 선택 항목 또한 느려졌으며 각 코드에 대해 하나씩 수행해야했습니다.

답변

1

... 난 당신이 스키마를 수정하고자하지 않은 가정, 그래서 난 내 answe 많은 도움이되지 않을 수도 있습니다 두려워하지만, 여기에 간다

한 가지 가능한 해결책은 시간 필드가하는 것 대신 'deprecation date'를 삽입 할 때까지 새로운 값으로 바뀔 때까지 비워 두십시오. 또 다른 방법은 '활성'열을 사용하여 테이블을 확장하는 것이지만 일부 중복성을 도입 할 수 있습니다.

기존 솔루션은 다른 입력이 유효해질 때까지 'Valid-To'필드가 비어있는 'Valid-From'및 'Valid-To'필드를 모두 가지는 것입니다. 이것은 트리거 등을 사용하여 쉽게 처리 할 수 ​​있습니다. 제약 조건을 사용하여 유효한 각 유형의 항목이 하나만 있는지 확인하여 데이터 무결성을 보장합니다.

공통점은 현재 필드 집합을 결정하는 단일 방법이 있다는 것입니다. 활성 사용자와 NULL 'Valid-To'또는 'deprecation date'또는 true 'active'가있는 모든 항목을 선택하기 만하면됩니다.

temporal databasesA consensus glossary of temporal database concepts 위키 피 디아 항목을 살펴 보는 데 관심이있을 수 있습니다.

6

실제로는 PostgreSQL에서 SELECT 구문에 "DISTINCT ON" 절이 있기 때문에 어렵지 않습니다 (DISTINCT ON은 표준 SQL이 아닙니다). 고유 한 코드 당 첫 번째 결과로 반환 된 결과를 제한합니다, 당신은 시간을 만들 내림차순으로 결과를 정렬하는 경우, 각의 최신를 얻을 수 있습니다

SELECT DISTINCT ON (code) code, content, createtime 
FROM metatable 
WHERE userid = 15 
ORDER BY code, createtime DESC; 

.

0

subselect는 이런 종류의 일을하는 표준 방법입니다. UserId, Code 및 Date에 대한 고유 제한이 필요하며 다음을 실행할 수 있습니다.

SELECT * 
FROM Table 
JOIN (
    SELECT UserId, Code, MAX(Date) as LastDate 
    FROM Table 
    GROUP BY UserId, Code 
) as Latest ON 
    Table.UserId = Latest.UserId 
    AND Table.Code = Latest.Code 
    AND Table.Date = Latest.Date 
WHERE 
    UserId = @userId 
관련 문제