使用MS SQL Server 2014.我需要选择其中(userid = 1或memberid = 1)的行,其中来自用户#1发送或接收的所有消息的max(messageid)值由messageid desc排序
我在这里尝试了解决方案:How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?,但由于用户可以发送或接收消息,解决方案只能部分解决我的问题。
消息表
messageid userid memberid message created
--------------------------------------------------------------
9 4 1 Hi 9 2016-05-09 01:50:59.423
8 4 1 Hi 8 2016-05-09 01:50:43.950
7 1 4 Hi 7 2016-05-09 01:50:35.310
6 1 4 Hi 6 2016-05-09 01:50:25.887
5 1 2 Hi 5 2016-05-08 23:49:41.610
11 2 1 Hi 11 2016-05-09 03:26:42.267
12 1 3 Hi 12 2016-05-09 05:06:11.030
1 1 2 Hi 1 2016-05-08 22:37:57.803
预期结果
messageid userid memberid message created
--------------------------------------------------------------
12 1 3 Hi 12 2016-05-09 05:06:11.030
11 2 1 Hi 11 2016-05-09 03:26:42.267
9 4 1 Hi 9 2016-05-09 01:50:59.423
查询我试过
DECLARE @userid bigint
SET @userid=1
SELECT mm.*
FROM messages mm
INNER JOIN
(SELECT memberid AS otherperson, MAX(m.messageid) AS MaxID
FROM messages m
WHERE m.userid=@userid
GROUP BY memberid
) groupedmm
ON mm.memberid = groupedmm.otherperson
AND mm.messageid = groupedmm.MaxID
UNION
SELECT mmm.*
FROM messages mmm
INNER JOIN
(SELECT userid AS otherperson, MAX(m.messageid) AS MaxID
FROM messages m
WHERE m.memberid=@userid
GROUP BY userid
) groupedmmm
ON mmm.userid = groupedmmm.otherperson
AND mmm.messageid = groupedmmm.MaxID
以上查询返回
messageid userid memberid message created
--------------------------------------------------------------
5 1 2 Hi 5 2016-05-08 23:49:41.610
7 1 4 Hi 7 2016-05-09 01:50:35.310
9 4 1 Hi 9 2016-05-09 01:50:59.423
11 2 1 Hi 11 2016-05-09 03:26:42.267
12 1 3 Hi 12 2016-05-09 05:06:11.030
答案 0 :(得分:3)
这似乎可以完成这项工作 - 如果您使用分区函数,则非常简单:
declare @user_id int
set @user_id = 1
declare @t table (messageid tinyint, userid tinyint, memberid tinyint, message varchar(17),
created datetime)
insert into @t(messageid, userid, memberid, message, created) values
(9 ,4 ,1 ,'Hi 9' ,'2016-05-09T01:50:59.423'),
(8 ,4 ,1 ,'Hi 8' ,'2016-05-09T01:50:43.950'),
(7 ,1 ,4 ,'Hi 7' ,'2016-05-09T01:50:35.310'),
(6 ,1 ,4 ,'Hi 6' ,'2016-05-09T01:50:25.887'),
(5 ,1 ,2 ,'Hi 5' ,'2016-05-08T23:49:41.610'),
(11 ,2 ,1 ,'Hi 11' ,'2016-05-09T03:26:42.267'),
(12 ,1 ,3 ,'Hi 12' ,'2016-05-09T05:06:11.030'),
(1 ,1 ,2 ,'Hi 1' ,'2016-05-08T22:37:57.803')
;With Ordered as (
select *,
ROW_NUMBER() OVER (PARTITION BY
CASE WHEN userid = @user_id THEN memberid else userid END
ORDER BY created desc) rn
from @t
where
userid = @user_id or
memberid = @user_id
)
select * from Ordered where rn = 1
结果:
messageid userid memberid message created rn
--------- ------ -------- ----------------- ----------------------- --------------------
11 2 1 Hi 11 2016-05-09 03:26:42.267 1
12 1 3 Hi 12 2016-05-09 05:06:11.030 1
9 4 1 Hi 9 2016-05-09 01:50:59.423 1
请注意使用CASE
表达式来导出PARTITION
值,基本上是"在WHERE
子句"中没有匹配的列。 。扩展到两列以上可能比较棘手。
答案 1 :(得分:1)
CREATE TABLE #D
(
MESSAGEID INT, USERID INT, MEMBERID INT, MESSAGE VARCHAR(10), CREATED DATETIME)
INSERT INTO #D VALUES
(9,4,1,'HI 9','2016-05-09 01:50:59.423'),
(8,4,1,'HI 8','2016-05-09 01:50:43.950'),
(7,1,4,'HI 7','2016-05-09 01:50:35.310'),
(6,1,4,'HI 6','2016-05-09 01:50:25.887'),
(5,1,2,'HI 5','2016-05-08 23:49:41.610'),
(11,2,1,'HI 11','2016-05-09 03:26:42.267'),
(12,1,3,'HI 12','2016-05-09 05:06:11.030'),
(1,1,2,'HI 1','2016-05-08 22:37:57.803')
SELECT TT.*
FROM #D TT
INNER JOIN
(SELECT USERID, MAX(CREATED) AS MAXDATETIME
FROM #D
GROUP BY USERID) GROUPEDTT
ON TT.USERID = GROUPEDTT.USERID
AND TT.CREATED = GROUPEDTT.MAXDATETIME