我有一张桌子:
MsgID MsgrUserID MsgdUserID MsgDate Message
1 1 4 6/12/2015 Jules - Did you pick up the blueprints?
2 4 1 6/15/2015 Yes, they're in my hands
3 4 1 6/15/2015 Let me know when you can talk
4 3 4 6/16/2015 Jules, let's meet tomorrow
5 1 4 6/17/2015 I'm available at 2 PM today
6 1 3 7/4/2015 Cindy, did you check your mail?
7 4 3 7/3/2015 OK, I'm free after 3PM
8 3 1 7/2/2015 Yes, there was nothing there
9 2 1 7/5/2015 Plan is going well. Just need more time
10 1 2 7/5/2015 OK, great. Let me know
我需要做的是获得一份总结所有通信的报告。它看起来像这样:
User: 1
Correspondence between you and 2: 2 Last correspondence: 7/5/2015
Correspondence between you and 3: 2 Last correspondence: 7/4/2015
Correspondence between you and 4: 4 Last correspondence: 6/17/2015
或类似的东西。所以,我需要弄清楚如何总结对应的数量,还要从原始表中获取其他信息。我遇到的问题是,我无法弄清楚如何将总和与原始表相关联,因为它是有条件的。有时,用户的ID位于Msgr(Messenger)字段中,有时它位于Msgd(消息传递)字段中。
我有这个怪物,但我知道#MyMsgs表的连接是错误的所在。
with cte as (
select
MessagedUserID as MessagedUserIDOrig,
MessagerUserID as MessagerUserIDOrig,
case when MessagerUserID < MessagedUserID
then MessagerUserID else MessagedUserID end MessagerUserID,
case when MessagerUserID > MessagedUserID
then MessagerUserID else MessagedUserID end MessagedUserID
from tmpMessaged
)
select MessagerUserID, MessagedUserID, count(*) as Contact
into #MyMsgs
from cte
WHERE MessagerUserID = @MyID
OR MessagedUserID = @MyID
group by MessagerUserID, MessagedUserID
SELECT
T1.*,
Mgr.UserName as MessagerName,
Mgr.UserID as UserID,
CASE WHEN T1.MessagedUserID = @MyID THEN Mgd.UserImg1 ELSE Mgr.UserImg1 END as UserImg1,
Mgd.UserName as MessagedName,
CC.Contact,
Mgd.LastLoginDate as LastOnline,
CASE WHEN T1.MessagedUserID = @MyID THEN 'Received' ELSE 'Sent' END as LContact,
LEFT(T1.[Message], 100) + '...' as [uMessage],
CASE WHEN T1.MessageViewed IS NULL THEN 'No' ELSE 'Yes' END as MsgViewed,
CASE WHEN T1.MessageFlag IS NULL THEN 'No' ELSE 'Yes' END as MsgFlagged
FROM [dbo].[tmpMessaged] T1
LEFT JOIN [dbo].[tmpUsers] Mgr
ON T1.[MessagerUserID] = Mgr.[UserID]
LEFT JOIN [dbo].[tmpUsers] Mgd
ON T1.[MessagedUserID] = Mgd.[UserID]
LEFT JOIN [dbo].[tmpMessaged] T2
ON T1.MessageID = T2.MessageID
LEFT JOIN #MyMsgs CC
ON CASE
-- WHEN T1.MessagerUserID = @MyID AND CC.MessagerUserID = T1.MessagerUserID THEN 1
WHEN T1.MessagedUserID = @MyID AND CC.MessagedUserID = T1.MessagedUserID THEN 1
ELSE 0
END = 1
WHERE
-- First grab the records where the User's ID is in the Messaged field
Mgd.[UserID] = @MyID
UNION
SELECT
T1.*,
Mgr.UserName as MessagerName,
Mgr.UserID as UserID,
CASE WHEN T1.MessagerUserID = @MyID THEN Mgr.UserImg1 ELSE Mgd.UserImg1 END as UserImg1,
Mgd.UserName as MessagedName,
CC.Contact,
Mgd.LastLoginDate as LastOnline,
CASE WHEN T1.MessagerUserID = @MyID THEN 'Sent' ELSE 'Received' END as LContact,
LEFT(T1.[Message], 100) + '...' as [uMessage],
CASE WHEN T1.MessageViewed IS NULL THEN 'No' ELSE 'Yes' END as MsgViewed,
CASE WHEN T1.MessageFlag IS NULL THEN 'No' ELSE 'Yes' END as MsgFlagged
FROM [dbo].[tmpMessaged] T1
LEFT JOIN [dbo].[tmpUsers] Mgr
ON T1.[MessagerUserID] = Mgr.[UserID]
LEFT JOIN [dbo].[tmpUsers] Mgd
ON T1.[MessagedUserID] = Mgd.[UserID]
LEFT JOIN [dbo].[tmpMessaged] T2
ON T1.MessageID = T2.MessageID
LEFT JOIN #MyMsgs CC
ON CASE
WHEN T1.MessagerUserID = @MyID AND CC.MessagerUserID = T1.MessagerUserID THEN 1
-- WHEN T1.MessagedUserID = @MyID AND CC.MessagerUserID = T1.MessagedUserID THEN 1
ELSE 0
END = 1
WHERE
-- Now grab the records where the User's ID is in the Messager field
Mgr.[UserID] = @MyID
ORDER BY T1.MessageDate DESC
答案 0 :(得分:2)
您可以直接在公用表表达式中进行聚合:
declare @myID int = 1;
with cte as (
select
case when MessagerUserID < MessagedUserID
then MessagerUserID else MessagedUserID end MessagerUserID,
case when MessagerUserID > MessagedUserID
then MessagerUserID else MessagedUserID end MessagedUserID,
count(*) MessageCount,
max(MessageDate) LastMessageDate
from tmpMessaged
group by
case when MessagerUserID < MessagedUserID
then MessagerUserID else MessagedUserID end,
case when MessagerUserID > MessagedUserID
then MessagerUserID else MessagedUserID end
)
select * from cte where MessagerUserID = @myID;
根据您的样本数据,这将导致:
MessagerUserID MessagedUserID MessageCount LastMessageDate
-------------- -------------- ------------ ---------------
1 2 2 2015-07-05
1 3 2 2015-07-04
1 4 4 2015-06-17
具有标题/详细信息等的特定格式可能在实际的报告应用程序中更好,尽管它当然也可能直接在服务器上进行(但无论如何谁使用SSMS进行漂亮的报告)。
答案 1 :(得分:0)
我问过发件人曾经是接收者并得到了我希望的答案(不)。有了这个规则,你可以&#34;欺骗&#34;并且对记录进行双重堆叠,将参与者1和参与者2交换为其中的一半,然后只关注自己选择该结构并将参与者1视为&#34;您的家伙&#34;和参与者2作为&#34;其他人&#34;。当发送者不能等于接收者时,你永远不会重复计算记录。
DECLARE @UserYouCareAbout int
SET @UserYouCareAbout = 1
SELECT CONVERT(nvarchar(max), GETDATE(), 101)
SELECT
'Correspondence between you and ' + CONVERT(nvarchar(max), [Message Participant 2]) + ': ' + STR(MAX(MsgDate), 4, 0) AS [Conversation With],
'Last correspondence: ' + CONVERT(nvarchar(max), MAX(MsgDate), 101) AS [Last Communication]
/*
--individual unformatted pieces
,
COUNT(MsgID) AS [MessageCount],
[Message Participant 2] AS [Other Guy],
MAX(MsgDate) AS [LastDate]
*/
FROM
(
(
SELECT
MsgID,
MsgrUserID AS [Message Participant 1],
MsgdUserID AS [Message Participant 2],
MsgDate
FROM
tmpMessaged
) --SentStuff
UNION ALL
(
SELECT
MsgID,
MsgdUserID AS [Message Participant 1], --note that
MsgrUserID AS [Message Participant 2], --these switched
MsgDate
FROM
tmpMessaged
) --RecStuff
) DerivedAllMessagesTwice
WHERE
[Message Participant 1] = @UserYouCareAbout
GROUP BY
[Message Participant 2]
这种简化消除了所有内联条件。
答案 2 :(得分:0)
请尝试以下代码: -
declare @MyID int = 1
create table #yourmsgtable (MsgID int, MsgrUserID int, MsgdUserID int, MsgDate date, Message varchar(max))
insert into #yourmsgtable values
(1,1,4,'6/12/2015','Jules - Did you pick up the blueprints?'),
(2,4,1,'6/15/2015','Yes, they''re in my hands'),
(3,4,1,'6/15/2015','Let me know when you can talk'),
(4,3,4,'6/16/2015','Jules, let''s meet tomorrow'),
(5,1,4,'6/17/2015','I''m available at 2 PM today'),
(6,1,3,'7/4/2015','Cindy, did you check your mail?'),
(7,4,3,'7/3/2015','OK, I''m free after 3PM'),
(8,3,1,'7/2/2015','Yes, there was nothing there'),
(9,2,1,'7/5/2015','Plan is going well. Just need more time'),
(10,1,2,'7/5/2015','OK, great. Let me know')
create table #tmpmsgtable(party1 int, party2 int, msgdate date)
insert into #tmpmsgtable
select MsgrUserID, MsgdUserID, MsgDate from #yourmsgtable where MsgrUserID = @MyID
union all
select MsgdUserID, MsgrUserID, MsgDate from #yourmsgtable where MsgdUserID = @MyID
select
'User : ' + convert(varchar(max),party1) 'Party 1',
'Correspondence between you and ' + convert(varchar(max),party2) + ' : ' + convert(varchar(max),count(*)) 'Party 2 Correspondence',
'Last correspondence : ' + convert(nvarchar(max),max(msgdate)) 'Last correspondence'
from #tmpmsgtable
group by party1, party2
drop table #tmpmsgtable
drop table #yourmsgtable
结果: -