在SQL Server中,如何选择多个字段(没有agregation函数)并将DISTINCT语句仅应用于一个特定字段?
例如:如果我有一个存储用户操作的表,那么伪模式将是这样的:
UserActions
------------
id,
User,
Action
insertDate
我想获取给定用户的最新操作,而不重复“Action”字段?
例如,如果表格内容为:
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 :(得分:5)
内部查询应为用户'john'选择每个操作的最大ID,外部查询将选择与内部查询中的id集合匹配的那些记录,因此您应该只获取每个操作的最后一个指定用户。
select id, user, action, insertDate
from userActions
where id in (select max(id)
from userActions
where user ='john'
group by action)
答案 1 :(得分:1)
值得考虑的另一种选择(在SQL Server 2008中;不确定SS 2005):
SELECT id, User, Action, InsertDate
FROM Table
WHERE User = 'john'
AND ROW_NUMBER()
OVER(PARTITION BY Action ORDER BY InsertDate DESC)
= 1
(看,马,没有聚合函数! - )
答案 2 :(得分:1)
忽略OP需要没有聚合函数(仍不确定为什么......)
我对给定答案的问题是:
所以考虑到这些需要构建一个更动态的查询
将2行添加到测试数据
7, john, update, 04/01/09
8, mark, insert, 01/02/09
答案没有给出OP想要的东西
这是我的第一稿快速 - 稍后会整理
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
...更新
第二版使用ID获取一个不同的行,特定用户可能会有多个行为,即测试数据是否也有以下行
9, john, delete, 06/01/09
然后你需要在行id 6和行id 9之间决定返回哪一个。我随意选择使用max(id),因为我猜数据很重要而不是行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
答案 3 :(得分: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)
}
}
答案 4 :(得分:0)
如果您有一组固定的操作,您可以为每个操作的TOP 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