我想使用SQL Server中的存储过程合并我的通知数据。我已经编写了查询,但是在这个查询中,我获得的不仅仅是多行中的用户数据。
我想合并关注者通知。喜欢"用户跟随用户b然后用户b"得到通知,例如"用户a开始关注你"。再次"用户c关注用户b"然后"用户b再次收到类似" "用户c关注你"。
再次"用户d再次关注用户b,然后用户b再次关注获取通知"。但是现在我想像这个通知那样合并"用户a,b和1个用户开始关注你"。
这是我的存储过程:
SELECT
N.NotificationId,
N.UserId,
N.ActionUserId,
(CASE WHEN N.NotificationTypeId = 1 THEN 1
WHEN N.NotificationTypeId = 7 THEN 3
ELSE
2
END) AS TypeId,
AU.ProfileImage,
AU.UserName,
N.IsRead,
(CASE WHEN N.NotificationTypeId = 1 THEN 1
WHEN N.NotificationTypeId = 7 THEN 3
ELSE 2
END) AS TypeId,
N.NotificationTypeId,
N.InsertDateTime
FROM
Notifications N
INNER JOIN
Users U ON N.UserId = U.UserId
INNER JOIN
Users AU ON N.ActionUserId = AU.UserId
ORDER BY
N.InsertDateTime DESC
这是我目前的o / p =>
NotificationId | UserId | ActionUserId | UserName | NotificationTypeId | InsertDateTime | ProfileImage
6 20 15 hbc 1 2017-06-22 17:14:16.803 20170416032403869.jpeg
5 20 16 tyu 1 2017-06-22 17:12:12.297 20170416031522534.jpeg
4 20 17 opl 1 2017-06-22 17:11:58.060 20170416031250102.jpeg
3 10 11 abc 1 2017-06-22 16:14:16.803 20170416032403867.jpeg
2 10 12 xyz 1 2017-06-22 16:14:12.297 20170416031522533.jpeg
1 10 13 rty 1 2017-06-22 16:13:58.060 20170416031250101.jpeg
这是我的例外情况o / p =>
NotificationId | UserId | ActionUserId | UserName | NotificationTypeId | InsertDateTime | ProfileImage | NotificationText
6 20 15 hbc 1 2017-06-22 17:14:16.803 20170416032403869.jpeg hbc,tyu and 1 other users followed you
3 10 11 abc 1 2017-06-22 16:14:16.803 20170416032403867.jpeg abc,xyz and 1 other users followed you
创建测试数据=>
declare @Notifications table(NotificationID int, UserID int, ActionUserID int, NotificationTypeID int, InsertDateTime datetime);
declare @Users table(UserID int, UserName nvarchar(10), ProfileImage nvarchar(50))
insert into @Notifications values (6,20,15,1,'2017-06-22 17:14:16.803'),(5,20,16,1,'2017-06-22 17:12:12.297'),(4,20,17,1,'2017-06-22 17:11:58.060'),(3,10,11,1,'2017-06-22 16:14:16.803'),(2,10,12,1,'2017-06-22 16:14:12.297'),(1,10,13,1,'2017-06-22 16:13:58.060');
insert into @Users values (15,'hbc','20170416032403869.jpeg'),(16,'tyu','20170416031522534.jpeg'),(17,'opl','20170416031250102.jpeg'),(10,'aaa',''),(11,'abc','20170416032403867.jpeg'),(12,'xyz','20170416031522533.jpeg'),(13,'rty','20170416031250101.jpeg');
答案 0 :(得分:2)
试试这个:
declare @Notifications table
(NotificationID int,
UserID int,
ActionUserID int,
NotificationTypeID int,
InsertDateTime datetime);
declare @Users table
(UserID int,
UserName nvarchar(10),
ProfileImage nvarchar(50))
insert into @Notifications values
(6,20,15,1,'2017-06-22 17:14:16.803'),
(5,20,16,1,'2017-06-22 17:12:12.297'),
(4,20,17,1,'2017-06-22 17:11:58.060'),
(3,10,11,1,'2017-06-22 16:14:16.803'),
(2,10,12,1,'2017-06-22 16:14:12.297'),
(1,10,13,1,'2017-06-22 16:13:58.060');
insert into @Users values (15,'hbc','20170416032403869.jpeg'),
(16,'tyu','20170416031522534.jpeg'),
(17,'opl','20170416031250102.jpeg'),
(10,'aaa',''),
(20,'bbb',''),
(11,'abc','20170416032403867.jpeg'),
(12,'xyz','20170416031522533.jpeg'),
(13,'rty','20170416031250101.jpeg');
declare @followCount table
(
userid int,
cnt int
)
INSERT INTO @followCount
select N.UserID, count(*)
FROM
@Notifications N
INNER JOIN
@Users U ON N.UserId = U.UserId
INNER JOIN
@Users AU ON N.ActionUserId = AU.UserId
GROUP BY n.UserID
declare @msg table
(
userid int,
NotificationMsg varchar(15)
)
INSERT INTO @msg
SELECT DISTINCT N.UserID, Stuff((SELECT ', ' + UserName
FROM
(SELECT UserID, UserName FROM (SELECT N.UserId,
AU.UserName,
ROW_NUMBER() OVER (PARTITION BY N.UserID ORDER BY N.InsertDateTime DESC) as rn
FROM
@Notifications N
INNER JOIN
@Users U ON N.UserId = U.UserId
INNER JOIN
@Users AU ON N.ActionUserId = AU.UserId
INNER JOIN
@followCount C on C.userid = N.UserID) t2 WHERE rn < 3) t2
WHERE t2.UserID = N.UserID
FOR XML PATH('')), 1, 2, '') AS NotificationMsg
FROM @Notifications N
; with cte as
(SELECT N.NotificationId,
N.UserId,
N.ActionUserId,
(CASE WHEN N.NotificationTypeId = 1 THEN 1
WHEN N.NotificationTypeId = 7 THEN 3
ELSE
2
END) AS TypeId,
AU.ProfileImage,
AU.UserName,
N.NotificationTypeId,
N.InsertDateTime,
m.NotificationMsg + CASE WHEN c.cnt > 2 THEN ' + '
+ FORMAT(c.cnt - 2, '0') + ' other users' END + ' followed you.' AS NotificationText,
ROW_NUMBER() OVER (PARTITION BY N.UserID ORDER BY N.InsertDateTime DESC) as rn
FROM
@Notifications N
INNER JOIN
@Users U ON N.UserId = U.UserId
INNER JOIN
@Users AU ON N.ActionUserId = AU.UserId
INNER JOIN
@followCount C on C.userid = N.UserID
INNER JOIN @msg M ON m.userid = N.UserID)
SELECT NotificationID, UserID, ActionUserID, UserName,
NotificationTypeID, InsertDateTime, ProfileImage, NotificationText
FROM cte WHERE rn = 1
请注意我必须为用户标识20添加一个条目。您提供的示例数据只生成一条记录。
使得它特别棘手的是,需要两个名字加上x个其他名字。这涉及几个中间步骤。很可能是一个比SQL更专业的人可以缩短它。另请注意,我只测试了这些数据。你需要检查更多和少于3个其他用户的数字,以确保它仍然是好的。