2017-08-05 12 views
2

SQL Serverのストアドプロシージャを使用して通知データをマージします。私はクエリを書いたが、このクエリでは、私は複数の行にユーザーデータ以上を取得しています。SQL Serverを使用して複数の行を1つの行にマージしますか?

フォロワーの通知をマージします。 「ユーザーはフォローしているユーザーbの後にユーザーb」のような通知を「ユーザーはフォローしているユーザー」のようになります。再び「ユーザーcはユーザーbに従う」、「ユーザーbは再びユーザーcのように通知を受け取りました」。

この場合も、「ユーザーdはユーザーBに続いて、ユーザーbは通知を受ける」と同じです。しかし今、私はこの通知のように、「ユーザーa、b、さらに1人のユーザーがフォローしています」のようにマージしたいと考えています。 =>

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 

これは私の/ P oを除外する=>

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 

作成

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:ここ

は私のストアドプロシージャですテストデータ=>

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'); 
+1

@TimBiegeleisen私のデータをマージする方法を教えてください。 – Edit

+1

@marc_sどうすればいいのか教えてください。 – Edit

+2

このような質問をするときは、次の情報を提供する必要があります。1)関連するテーブルのステートメントを作成します。 2)INSERT文を使用して、結果をテストするのに十分なテスト・データ(実際のデータである必要はありません)をこれらの表に移入します。 3)試験データが与えられたときに所望の出力をサンプリングする。次に、あなたは助けを受けるより良い機会を得ます。 –

答えて

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 

は、私は、ユーザーID 20のためにあなたが1つのレコードだけを生産しましたサンプルデータをエントリを追加する必要がありましたのでご注意ください。

特に難しいのは、2つの名前に加えて他の2つの名前でした。これにはいくつかの中間ステップが必要でした。それは、私がこれを短縮することができるよりも、SQLでもっと精巧な人がいるかもしれません。また、私はこのデータだけでテストしたことに注意してください。あなたは3人以上のユーザーとそれ以下のユーザーをチェックして、それでもすべてが良いことを確認する必要があります。

関連する問題