2016-07-20 2 views
0

다른 고유 식별자가있는 한 중복 행을 제한하지 않는 열악한 디자인의 데이터베이스로 작업하고 있습니다.T-SQL : 그룹화에서 마지막으로 수정 된 행을 얻는 방법

테이블 중 하나에서 주어진 사용자는 속성 및 속성 값을 가질 수 있습니다. 일반적으로 사용자는 속성을 한 번만 사용하지만 디자인이 좋지 않아서 테이블에 중복 된 항목이 많아 지므로 이제는 그 정리를 정리해야합니다. 이는 CRM 소프트웨어가 직원 프로필을 수정할 때 행이 존재하는지 항상 확인하지는 않지만 대신 중복 값이있는 새로운 행을 만듭니다.

다음 쿼리는 중복 값을 반환

SELECT ua.ID AS LineID 
    ,ua.Modified AS LineLastModifiedDate 
    ,u.FullName AS EmployeeName 
    ,a.Name AS AttributeName 
    ,ua.value AS AttributeValue 

FROM UserAttributes AS ua 
    INNER JOIN Users AS u ON ua.userid = u.id 
    INNER JOIN Attributes AS a ON ua.AttributeID = a.ID 

WHERE EXISTS (
    SELECT NULL 
    FROM UserAttributes as ua2 
    WHERE ua2.UserID = ua.UserID 
     AND ua2.AttributeID = ua.AttributeID 
     AND ua2.ID != ua.ID 
    ) 

을 그리고이 같은 결과를 얻게

LineID LineLastModifiedDate EmployeeName AttributeName AttributeValue 
------ ----------------------- ------------- --------------- --------------- 
15  2016-01-01    Employee1  EmployeeNumber 15    
19  2016-07-20    Employee1  EmployeeNumber 15    
35  2016-01-01    Employee2  EmployeeSex  M    
96  2016-07-20    Employee2  EmployeeSex  M    
21  2016-03-03    Employee1  SickDays  3    
99  2016-07-10    Employee1  SickDays  5    

내가이 쿼리에서 시작 달성하기 위해 필요한 것은 : 같은 EmployeeName의 foreach는 그룹화 및 AttributeName, 다음과 같은 결과를 기대하는 마지막 수정 된 라인을 제공하십시오 :

LineID LineLastModifiedDate EmployeeName AttributeName AttributeValue 
------ ----------------------- ------------- --------------- --------------- 
19  2016-07-20    Employee1  EmployeeNumber 15    
96  2016-07-20    Employee2  EmployeeSex  M 
99  2016-07-10    Employee1  SickDays  5       

이를 수행하기 위해 쿼리를 어떻게 수정할 수 있습니까?

-M

답변

2
;WITH CTE 
AS 
(
SELECT ua.ID AS LineID 
    ,ua.Modified AS LineLastModifiedDate 
    ,u.FullName AS EmployeeName 
    ,a.Name AS AttributeName 
    ,ua.value AS AttributeValue 
    ,ROW_NUMBER() OVER (PARTITION BY EMPLOYEENAME,EMPLOYEESEX ORDER BY UA.Modified DESC) AS RN 
FROM UserAttributes AS ua 
    INNER JOIN Users AS u ON ua.userid = u.id 
    INNER JOIN Attributes AS a ON ua.AttributeID = a.ID 

WHERE EXISTS (
    SELECT NULL 
    FROM UserAttributes as ua2 
    WHERE ua2.UserID = ua.UserID 
     AND ua2.AttributeID = ua.AttributeID 
     AND ua2.ID != ua.ID 
    ) 
) 
SELECT * FROM cte where rn=1 
+0

이것은 실제로 실제로 잘되었습니다. 고맙습니다 ! –

0

당신은 조인을 사용하여 다음 최대 값을 꺼내 경우 다음과 같이 행 번호 또는 스키마를 사용 할 수 있습니다 감사합니다. 아마도 날짜별로 유대 관계를 가질 수는 없을 것입니다.

select ... 
from 
    UserAttributes as ua 
    inner join 
    (
    select 
     UserID, AttributeID, 
     max(LineLastModifiedDate) as MaxLineLastModifiedDate 
    fromUserAttributes 
group by UserId 
    ) as max_ua 
     on  max_ua.UserID = ua.UserID 
      and max_ua.AttributeID = max_ua.AttributeID 
      and max_ua.MaxLineLastModifiedDate = ua.LineLastModifiedDate 
    ... 
관련 문제