2016-07-20 1 views
0

異なる固有識別子を持つ限り、重複する行を制約しない設計が貧弱なデータベースを使用しています。T-SQL:グループ化から最後に変更された行を取得する方法

テーブルの1つで、特定のユーザーは、属性とその属性の値を持つことができます。通常、ユーザーは属性を1回だけ持つことになりますが、設計が貧弱であるため、テーブルに重複しています。これは、従業員プロファイルを変更したときに行が存在するかどうかを常に確認するのではなく、重複値を持つ新しい行を作成するためです。

次のクエリでは、重複する値を返します。

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 
    ... 
関連する問題