0

我继承了一个使用 SQL Server (2008 R2) 的系统,其中包含两个涵盖系统消息传递的表。一条消息具有一对多的关系,它可以发送给多个用户。

主表 Messaging 如下所示:

Id (PK, auto increment)
Subject
MessageBody
CreatorEmployeeId
ConversationId
IsConversationStarter (bool)

辅助表 MessagingDetails 如下所示:

ID (PK, auto increment)
MessageId (FK to Messaging PK)
RecipientEmployeeId
ConversationId
IsRead (bool)

如果不清楚,则会将一条新消息放入 Messaging 表中,其中包含创建该消息的员工 ID,并创建新的对话 ID。然后将 X 行插入到 MessagingDetails 中,每个收件人一个,引用返回到 Messaging 表并使用相同的对话 ID。

任何新的回复看起来都一样,回复消息进入消息表,收件人详细信息使用相同的对话 ID 进入消息详细信息,这样您就可以将整个消息线程拉一个数字。

当您尝试计算您已创建或已发送给您的所有未读邮件时,这会变得很草率。这是一个现有的查询,它获取系统中其他用户发送给登录用户的所有未读消息,他们最初是在其中创建消息的

SELECT * FROM dbo.Messaging m
INNER JOIN dbo.MessagingDetails m1 on m.Id = m1.MessageId
INNER JOIN dbo.MessagingDetails m2 on m1.ConversationId = m2.ConversationId
WHERE m1.RecipientEmployeeId = @employeeId
AND m.IsConversationStarter = 1
AND m.ConversationId = m1.ConversationId
AND m2.IsRead = 0 
AND m2.RecipientEmployeeId == @employeeId

然后要查找员工创建但有未读回复的所有消息,您必须执行几乎相同的查询,将WHERE子句的第一部分换成:

m.CreatorEmployeeId = @employeeId

我讨厌内部加入同一张桌子两次,一次是自己。鉴于上述架构,是否有更好的方法来编写这些查询?

4

2 回答 2

1

为了摆脱第二个 join on dbo.MessagingDetails,这个查询应该和你的一样。

SELECT * FROM dbo.Messaging m
INNER JOIN dbo.MessagingDetails m1 on m.Id = m1.MessageId
WHERE m1.RecipientEmployeeId = @employeeId
AND m.IsConversationStarter = 1
AND m.ConversationId = m1.ConversationId
AND EXISTS(SELECT * FROM dbo.MessagingDetails m2
    WHERE m1.ConversationId = m2.ConversationId
    AND m2.IsRead = 0 AND m2.RecipientEmployeeId == @employeeId)

我认为它不会更有效率,但您必须检查执行计划。

于 2012-08-11T15:14:54.873 回答
1

对于“员工发送的未发送回复的消息”,我认为这可以解决问题:

with EmployeeCreatedMessages as (
     select distinct MessageId
     from Messaging
     where m.CreatorEmployeeId = @employeeId
    )
select distinct MessageId
from MessageDetails md
where md.MessageId in (select MessageId from EmployeeCreatedMessages) and
      md.IsRead = false

我不确定您想要关于该消息的哪些信息。这只是给出消息ID。

同样的方法适用于其他人发送给用户的所有消息:

with OtherCreatedMessages as (
     select distinct MessageId
     from Messaging
     where m.CreatorEmployeeId <> @employeeId
    )
select distinct MessageId
from MessageDetails md
where md.MessageId in (select MessageId from OtherCreatedMessages) and
      md.IsRead = false and
      md.RecipientEmployeeId = @employeeid

你的描述和你的问题没有提到conversionid。这相关吗?

于 2012-08-11T15:29:56.753 回答