2012-10-22 1 views
1

인 'K', 각 사용자에 대한 가장 최근의 기록을 얻기 나는 SQL Server의 다음 표했다 :값이 액션 ID가 null의 경우, 또는 그 상태가 1

user_id, value, date, action_id 
---------------------------------- 
1   A 1/3/2012  null 
1   K 1/4/2012  null 
1   B 1/5/2012  null 
2   X 1/3/2012  null 
2   K 1/4/2012  1 
3   K 1/3/2012  null 
3   L 1/4/2012  2 
3   K 1/5/2012  3 
4   K 1/3/2012  null 


action_id, state 
---------------------------------- 
1   0 
2   1 
3   1 
4   0 
5   1 

나는 가장 최근을 반환해야 USER_ID 경우 1

user_id, value, date, action_id 
---------------------------------- 
3   K 1/5/2012  3 
4   K 1/3/2012  null 

는, 가장 최근의 값이 B입니다 : 값이 'K'는 각 사용자에 대한 기록은 작업 ID는 여기에 내가 원하는 결과가 설정되어 널 (null) 중 하나 또는 그 상태가 1로 설정되어 액션 ID가 null이므로 가장 최근의 레코드라고 생각하지만 값이 K가 아닙니다.

USER_ID 2의

는, 가장 최근의 값은 K이지만, 액션 ID 1은 상태 0을 가지고, 그래서 나는 X에 폴백하지만 X는

USER_ID 3과 4는 간단 K.

없습니다.

저는 Linq에서 ASP.NET의 SQL 쿼리에 관심이 있습니다 만, 현재 T-SQL도 괜찮습니다.

답변

1

SQL 쿼리는 다음과 같습니다

Select Top 1 T1.* from Table1 T1 
LEFT JOIN Table2 T2 
ON T1.action_id = T2.action_id 
Where T1.Value = 'K' AND (T1.action_id is null or T2.state = 1) 
Order by T1.date desc 

LINQ 쿼리 :

var result = context.Table1.Where(T1=> T1.Value == "K" 
         && (T1.action_id == null || 
          context.Table2 
          .Where(T2=>T2.State == 1) 
          .Select(T2 => T2.action_id).Contains(T1.action_id))) 
         .OrderByDescending(T => T.date) 
         .FirstOrDefault(); 

행운을 빕니다!

+0

나는 T1.action_id가 null 인 부분을 잊어 버린 것 같습니다. 이러한 쿼리를 모두 업데이트 할 수 있습니까? T-SQL 쿼리의 where 절은 "T1.value = 'K'이고 T1.action_id는 null이거나 T2.state = 1입니다." – Mark13426

+0

@ Mark13426 감사합니다. 내 대답을 업데이트 할게. –

+0

감사합니다. linq 쿼리도 업데이트 할 수 있습니까? :) – Mark13426

0

데이터베이스에서 가장 최근의 항목 만 선택하는 TOP 1이 아니라 사용자 사양에 설명 된대로 모든 사용자의 최상위 항목을 선택합니다. 나는 당신의 테이블이 usersactions라는 것을 여기에 있으리라 믿고있어 :

WITH usersactions as 
    (SELECT 
     u.user_id, 
     u.value, 
     u.date, 
     u.action_id, 
     ROW NUMBER() OVER (PARTITION BY u.user_id ORDER BY u.date DESC, u.action_id DESC) as row 
    FROM users u 
    LEFT OUTER JOIN actions a ON u.action_id = a.action_id 
    WHERE 
     u.value = 'K' AND 
     (u.action_id IS NULL OR a.state = 1) 
) 
SELECT * FROM usersactions WHERE row = 1 

을 또는 당신은 CTE 사용하지 않으려면 :이 쿼리는 결과 세트를 원하는 돌아갑니다

SELECT * FROM 
    (SELECT 
     u.user_id, 
     u.value, 
     u.date, 
     u.action_id, 
     ROW NUMBER() OVER (PARTITION BY u.user_id ORDER BY u.date DESC, u.action_id DESC) as row 
    FROM users u 
    LEFT OUTER JOIN actions a ON u.action_id = a.action_id 
    WHERE 
     u.value = 'K' AND 
     (u.action_id IS NULL OR a.state = 1) 
) useractions 
WHERE row = 1 
0

을 :

SELECT 
     * 
    FROM 
    (
     SELECT 
      user_id 
      ,value 
      ,date 
      ,action_id 
      ,ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY date DESC) RowNum 
     FROM 
      testtable 
     WHERE 
      value = 'K' 
    ) testtable 
    WHERE 
     RowNum = 1 
0

user_id와 날짜 조합이 고유 한 경우 다음 방법을 시도 할 수도 있습니다. 조인 할 술어의 순서를 가져올 수 있는지 확인하십시오. 색인을 사용하는 방법 :

SELECT 
     testtable.* 
    FROM 
     (
      SELECT 
       user_id 
       ,MAX(date) LastDate 
      FROM 
       testtable 
      WHERE 
       value = 'K' 
      GROUP BY 
       user_id 
     ) tblLastValue 
    INNER JOIN 
     testtable 
    ON 
     testtable.user_id = tblLastValue.user_id 
    AND 
     testtable.date = tblLastValue.LastDate 
관련 문제