1

我在 SQL Server 中有以下表:

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

我需要返回值为“K”的每个用户的最新记录,操作 id 为 null 或其状态设置为 1。这是我想要的结果集:

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

对于user_id 1,最近的值为B,它的action id为null,所以我认为这是最近的记录,但它的值不是K。

对于user_id 2,最近的值是K,但是action id 1的状态是0,所以我回退到X,但是X不是K。

user_id 3 和 4 很简单。

我对 ASP.NET 中的 Linq to SQL 查询感兴趣,但现在 T-SQL 也很好。

4

4 回答 4

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();

祝你好运 !!

于 2012-10-22T16:28:55.870 回答
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
于 2012-10-23T08:38:36.270 回答
0

如果 user_id 和 date 组合是唯一的,您也可以尝试以下方法确保获取连接中谓词的顺序以便能够使用索引:

    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
于 2012-10-23T08:45:07.027 回答
0

这将为您的规范中描述的所有用户选择顶部条目,而不是TOP 1仅选择数据库中的最新条目。我在这里假设您的表被命名为users并且actions

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
于 2012-10-22T16:34:24.837 回答