2009-05-31 2 views
1

SQL Server에서 많은 필드를 선택하고 (agregation 함수 제외) DISTINCT 문을 하나의 특정 필드에만 적용 할 수 있습니까?하나의 특정 필드에만 DISTINCT를 적용하는 여러 필드 선택

예를 들어

:

UserActions 
------------ 
id, 
User, 
Action 
insertDate 

I 필드를 반복하지 않고 지정된 사용자의 최신 작업을 얻으려면 '내가 사용자 작업을 저장하는 테이블이있는 경우, 의사 스키마는 다음과 같이 될 것이다 동작'?

1, john, update, 01/01/09 
2, john, update, 01/02/09 
3, john, update, 01/03/09 
4, john, delete, 01/04/09 
5, john, insert, 01/05/09 
6, john, delete, 01/06/09 

나는 좀하고 싶습니다 : 사전에

6, john, delete, 01/06/09 
5, john, insert, 01/05/09 
3, john, update, 01/03/09 

많은 감사를 표 내용이있는 경우 예를 들어

.

+0

짧은 답변은 DISTINCT로 수행 할 수 없다는 것입니다. 결과 세트에서 MAX (insertDate)를 반환하는 것처럼 보입니다. – spencer7593

답변

5

내부 쿼리의 최대 ID를 선택해야합니다 사용자 'john'에 대한 각 작업의 경우 외부 쿼리는 내부 쿼리의 ID 컬렉션과 일치하는 레코드를 선택하므로 지정된 사용자에 대한 각 작업의 마지막 만 가져와야합니다. 고려 가치가

select id, user, action, insertDate 
from userActions 
where id in (select max(id) 
       from userActions 
       where user ='john' 
       group by action) 
+0

? MAX는 집계 함수입니다. – dkretz

+0

우수! 감사! –

+0

결과 세트가 스펙을 충족시킵니다. OP 질문은 DISTINCT를 사용하여 결과 세트를 얻는 방법이었습니다. 짧은 대답은 DISTINCT를 사용하지 않는 것입니다. – spencer7593

0

SQL 만 사용하는 방법을 모르겠습니다. 전체 쿼리 (InsertDate DESC로 정렬하려는 것처럼 보입니다)를 수행 한 다음 수동으로 원하는 것만 가져올 수 있습니다.

set s = new set() 
while (has more results) { 
    var r = next result 
    if (!s.contains(r)) { 
     process result 
     s.add(r) 
    } 
} 
+0

순수 SQL 응답보다 느리게 실행되고 많은 불필요한 행을 반환 할 수 있습니다. –

0

당신이 작업의 고정 세트가있는 경우, 당신은 함께 결과 상위 각 1, 노동 조합에 대한 쿼리를 작성할 수

SELECT TOP 1 [id], [User], [InsertDate] 
FROM [UserActions] 
WHERE [Action] = 'insert' 
ORDER BY [InsertDate] DESC 

UNION 

SELECT TOP 1 [id], [User], [InsertDate] 
FROM [UserActions] 
WHERE [Action] = 'update' 
ORDER BY [InsertDate] DESC 

UNION 

SELECT TOP 1 [id], [User], [InsertDate] 
FROM [UserActions] 
WHERE [Action] = 'delete' 
ORDER BY [InsertDate] DESC 
+1

ORDER BY DESC를 사용하는 TOP 1은 실제로 집계 함수입니다. – dkretz

1

하나의 대안 (SQL Server 2008의, 2005 SS에 대해 확실하지) :

SELECT id, User, Action, InsertDate 
FROM Table 
WHERE User = 'john' 
AND ROW_NUMBER() 
    OVER(PARTITION BY Action ORDER BY InsertDate DESC) 
    = 1 

이 (보고, 엄마, 아니 집계 함수 -!)

+0

이렇게하면 다음과 같은 결과를 얻을 수 있습니다. "창 함수는 SELECT 또는 ORDER BY 절에만 나타날 수 있습니다." –

+0

SS'05에 대한 쉬운 해결 방법 (그냥 중첩 된 SELECT)이 http://weblogs.sqlteam.com/jeffs/에있는 SS 2005의 문제 중 하나라고 생각했습니다. archive/2007/03/28/60146.aspx (하지만 SS 2008에서 여전히 필요하다고 생각하지는 않습니다.) –

+0

두 번째 @SantiagoCorredoira. 같은 오류가 발생하고 SQL Server 2008을 사용하고 있습니다.이 코드는 작동하지 않습니다. – danielson317

1

작전이 필요로 무시 집계 함수가 없음 (여전히 확실하지 않음 ...)

주어진 답변에 대한 문제는 다음과 같습니다.

  1. 다른 사용자를 허용하는 것이 동적이 아닙니다. '마크'라고 말하십시오.
  2. 조치의 최대 (ID)가 최신 조치와 일치한다고 가정합니다. 테스트 데이터는이를 제안하지만 그 가정은 아닙니다. 원칙적으로.

너무 마음에 사람들과보다 동적 인 쿼리는 대답은 영업 이익은

를 원하는 것을 제공하지 않습니다 테스트 데이터

7, john, update, 04/01/09 
8, mark, insert, 01/02/09 

에 추가 2 개 이상의 행과

를 구축 할 필요가 나중에

select 
    userActions.id, 
    userActions.[user], 
    userActions.Action, 
    userActions.insertDate 

from 
userActions 
join 
    (
    select 
     [user], action, max(insertdate) as maxinsertdate 
    from userActions 
    group by 
     [user], action 
    ) aggsubquery 
    on userActions.[user] = aggsubquery.[user] 
     and userActions.action = aggsubquery.action 
     and userActions.insertdate = aggsubquery.maxinsertdate 
을 정돈합니다 -

여기 빨리 내 첫 번째 초안의

업데이트 ...

2 버전은 테스트 데이터는 당신이하고자 다음 행

9, john, delete, 06/01/09 

이 있다면 즉, 특정 사용자에 의해 동작 하나 이상의 occurance이있을 수 있습니다 별개의 행을 얻을 수있는 ID를 사용하여 행 ID 6과 행 ID 9 중 어떤 것을 리턴할지 결정해야합니다. 데이터가 중요하고 행 ID가 아닌 것 같아서 max (id)를 사용하기로했습니다.

select 
    max(userActions.id) as id, 
    userActions.[user], 
    userActions.Action, 
    userActions.insertDate 
from 
userActions 
join 
    (
    select 
     [user], action, max(insertdate) as maxinsertdate 
    from userActions 
    group by 
     [user], action 
    ) aggsubquery 
    on userActions.[user] = aggsubquery.[user] 
     and userActions.action = aggsubquery.action 
     and userActions.insertdate = aggsubquery.maxinsertdate 
group by 
    userActions.[user], 
    userActions.Action, 
    userActions.insertDate 
관련 문제