我有一个“聊天”应用程序,我们在其中有一组用户之间的聊天。因此,一个用户可以成为多个组的一部分。
用户登录后,我们必须显示所有用户组及其消息。
但是,我们在登录时为每个群组消息提供了100个消息的桶/限制。意味着我们将为每个组仅向用户显示100条消息(最新消息),并显示其余消息,其中有一个按钮“加载早期消息”。
但是这100条消息的限制可能会在以下情况的基础上发生变化 -
如果每个组的所有消息都是Read,我们只需要显示100条消息(根据桶大小)。
我们必须显示每个组的所有UnRead消息,没有未读消息的存储桶。
最后一个场景是Read& UnRead消息。
因此,根据上述情况,我们必须在所有情况下显示所有UnRead消息是否超过桶大小。
以下是我们正在使用的表格 -
(1) Group
表:
GroupId(PK) GroupName
g1 Group_A
g2 Group_B
g3 Group_C
g4 Group_D
g5 Group_E
(2) ChatMessage
(此处GroupId
为FKey)
ChatMessageId(PK) GroupId(FK) Message CreatedDate
m1 g1 hi 25 Jan, 2017
m2 g2 hi1 26 Jan, 2017
m3 g1 hi2 25 Jan, 2017
m4 g1 hi3 25 Jan, 2017
m5 g3 hi4 27 Jan, 2017
m6 g4 hi5 28 Jan, 2017
m7 g5 hi6 29 Jan, 2017
m8 g2 hi7 26 Jan, 2017
m9 g3 hi8 27 Jan, 2017
m10 g4 hi9 30 Jan, 2017
(3) ChatMessageMember
(ChatMessageId和GroupId是FKey在这里)
MemberId ChatMessageId GroupId UserId ISMessageRead CreatedDate
cm1 m1 g1 111 Yes 25 Jan, 2017
cm2 m1 g1 222 Yes 25 Jan, 2017
cm3 m2 g2 111 No 26 Jan, 2017
cm4 m2 g2 222 Yes 26 Jan, 2017
cm5 m3 g1 111 No 25 Jan, 2017
cm6 m3 g1 222 Yes 25 Jan, 2017
cm7 m4 g1 111 No 25 Jan, 2017
cm8 m4 g1 222 Yes 25 Jan, 2017
cm9 m5 g3 111 Yes 27 Jan, 2017
cm10 m5 g3 222 Yes 27 Jan, 2017
cm11 m6 g4 111 No 25 Jan, 2017
cm12 m6 g4 222 No 25 Jan, 2017
cm13 m7 g5 111 No 29 Jan, 2017
cm14 m7 g5 222 No 29 Jan, 2017
cm15 m8 g2 111 Yes 26 Jan, 2017
cm16 m8 g2 222 Yes 26 Jan, 2017
cm17 m9 g3 111 Yes 27 Jan, 2017
cm18 m9 g3 222 Yes 27 Jan, 2017
cm19 m10 g4 111 Yes 30 Jan, 2017
cm20 m10 g4 222 Yes 30 Jan, 2017
我们使用以下标准来获取记录 -
select cmm.*
from ChatMessageMember cmm
where UserId = 111 and CreatedDate <= '31 Jan, 2017'
所以根据上面的查询记录应该基于“UserId”和给定的“Date”。这里我们使用CreatedDate作为endTime意味着我们必须选择记录直到DateTime。但对于起点,我们有两种情况 -
让我们从结束时间开始,所以起点将是第100条记录,但如果第100条记录是“UnRead”,那么我们必须选择记录,直到序列中的最后一条“UnRead”记录(直到我们没有得到任何记录) “阅读”记录。
但如果我们在第100个位置找到任何“阅读”记录,那么这将是我们的起点。
在这个我必须处理查询性能的复杂场景中,有人可以帮助我。
仅供参考,我使用的是SQL Server 2012和VS 2015.
更新 有关输出,请查看以下方案 -
please check the below table. For ex the bucket/limit is 3 and CreatedDate
is "30 Jan, 2017". So according to limit and Date filter the messages
should be m7,m6 & m5 for group 1 (g1). But there is an "UnRead" messages
ahead after 3 messages (at position m4 & m2). So we have to pick records
till last "UnRead" message from CreatedDate. Means from m7 to m2. So
messages will be (m2,m3,m4,m5,m6,m7).
Message IsMessageRead GroupId CreatedDate
m1 yes g1 26 Jan, 2017
m2 no g1 27 Jan, 2017
m3 yes g1 27 Jan, 2017
m4 no g1 27 Jan, 2017
m5 no g1 27 Jan, 2017
m6 yes g1 27 Jan, 2017
m7 no g1 28 Jan, 2017
答案 0 :(得分:0)
WITH
messages (row_number, memberid, chatmessageid, groupid, userid, ismessageread, createddate) AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY ismessageread ASC) rn
, memberid
, chatmessageid
, groupid
, userid
, ismessageread
, createddate
FROM
ChatMessageMember cmm
WHERE
UserId = 111
AND CreatedDate <= '31 Jan, 2017'
),
messages_summary (num_unread) AS
(
SELECT
SUM(CASE WHEN ismessageread = 'No' THEN 1 ELSE 0 END) num_unread
FROM
messages
)
SELECT
*
FROM
messages
WHERE
rn <= (
SELECT
CASE WHEN num_unread > 100 THEN num_unread ELSE 100 END num_messages_to_return
FROM
messages_summary
)