【问题标题】:Messaging Functionality Creating Sql query and Database View消息功能创建 Sql 查询和数据库视图
【发布时间】:2011-10-01 02:27:52
【问题描述】:

鉴于以下情况:

我需要能够获取给定用户参与的所有线程的列表,首先按最近的消息排序,仅显示最近的消息(每个线程 1 条消息)

这是上面的 SQL 查询:

SELECT
    Message.MessageId,
    Message.CreateDate,
    Message.Body,
    Login.Username,
    (SELECT MessageReadState.ReadDate
        FROM MessageReadState
        WHERE MessageReadState.MessageId = Message.MessageId
            AND MessageReadState.LoginId = 2) AS ReadState
FROM Message INNER JOIN Login ON Message.SenderLoginId = Login.LoginId
WHERE Message.MessageId IN (
    SELECT Max(Message.MessageId)
    FROM MessageThreadParticipant
    INNER JOIN Message
        ON MessageThreadParticipant.MessageThreadId = Message.MessageThreadId
    WHERE MessageThreadParticipant.LoginId=2
    GROUP BY MessageThreadParticipant.MessageThreadId
)
ORDER BY Message.CreateDate DESC;

它的工作方式是这样的。一个 LoginId 1 向一个 LoginId 2 发送一条消息:

  1. 创建一个新线程并将一条记录插入到 MessageThread 中

  2. 一条新记录被添加到消息表中,上面的treadId

  3. MessageThreadParticipant 中插入了两条记录(Sender LoginId 和 Recipient LogiId)

    当用户打开他/她的消息列表时,MessageReadState 将更新消息的 ReadDate。

问题: 我想创建一个视图,我可以在其中简单地过滤 LoginId(我将使用 LINQ)。但是我不能用上面的查询来做到这一点(因为我需要在 sql 语句中的某处传递 loginId)。有没有办法以允许我查看的方式修改上述 SQL 查询?这是什么?

编辑: 我想我有,但我不确定这是否是最好/最有效的解决方案:

SELECT
    Message.MessageId,
    Message.MessageThreadId,
    Message.SenderLoginId,
    Mtp.LoginId,
    Login.Username,
    Message.CreateDate,
    Message.Body,
    (SELECT MessageReadState.ReadDate
        FROM MessageReadState
        WHERE MessageReadState.MessageId = Message.MessageId
            AND MessageReadState.LoginId = Mtp.LoginID) AS ReadState
FROM Message 
    INNER JOIN Login ON Message.SenderLoginId = Login.LoginId
    INNER JOIN MessageThreadParticipant Mtp ON Mtp.MessageThreadId = Message.MessageThreadId
WHERE Message.MessageId IN (
    SELECT Max(Message.MessageId)
    FROM MessageThreadParticipant
    INNER JOIN Message
        ON MessageThreadParticipant.MessageThreadId = Message.MessageThreadId
    WHERE MessageThreadParticipant.LoginId=Login.LoginID
    GROUP BY MessageThreadParticipant.MessageThreadId
)
ORDER BY Message.CreateDate DESC;

【问题讨论】:

  • 您需要 loginId 是顶级选择中的一个字段,即删除各种 .LoginId = 2 部分,在选择列表中包含 LoginId 并适当地加入。
  • 在MessageThreadParticipant中,如何确定哪个LoginID是发件人,哪个是收件人?
  • 当你想通过 LoginID 过滤时,你是按 Sender 还是 Recipient 过滤?或者两者兼而有之?
  • 1. MessageThreadParticipant -> 仅列出参与者,消息表有一个名为“SenderLoginid”的字段 2. 我只想要每个给定 LoginId 的所有消息线程(线程中的最新消息)的列表。

标签: sql database tsql sql-server-2008


【解决方案1】:

这是否符合您的要求?

SELECT
  Login.LoginID,
  Login.Username,
  Message.MessageThreadID,
  Message.MessageId,
  Message.CreateDate,
  Message.Body,
  Sender.LoginID                     AS SenderLoginID,
  Sender.Username                    AS SenderUsername,
  MessageReadState.ReadDate          AS RecipientReadDate
FROM
  Login
INNER JOIN
  MessageThreadParticipant
    ON MessageThreadParticipant.LoginId = Login.LoginID
-- This gives all threads every LoginID has ever participated in

CROSS APPLY
  (SELECT TOP 1 * FROM Message WHERE ThreadId = MessageThreadParticipant.MessageThreadId ORDER BY CreateDate DESC) AS Message
-- This gives the newest message for each of those threads.
-- The Login.LoginID could be either the Sender or Recipient

INNER JOIN
  Login AS [Sender]
    ON Sender.LoginID = Message.SenderLoginID
LEFT JOIN
  MessageReadState
    ON  MessageReadState.MessageID = Message.MessageID
    AND MessageReadState.LoginId <> Sender.LoginID
-- This gets the Sender's details, and tries to get whether the recipient read the message
-- It assumes the only MessageReadState entries are for the Sender and Recipient.

ORDER BY
  Message.CreateDate DESC;

【讨论】:

  • 快到了。对于 LoginId 2,ReadDate 应该为 null 而不是。 (我在 MessageReadDate 中只有 1 条记录,发件人的有效日期)收件人尚未阅读邮件。
  • 当前代码选择收件人的MessageReadState 记录作为是(此消息,但不是发件人的登录ID)。您有更简洁的方法来识别正确的记录吗? (例如,Message 表是否有 RecipientLoginID 字段?可能会建议您包含这些表的架构,以便我们知道我们正在使用什么。)
  • 我认为这行得通: LEFT JOIN MessageReadState ON MessageReadState.MessageID = Message.MessageID AND MessageReadState.LoginId = Login.LoginID
  • Login.LoginID 不一定是收件人,也可能是发件人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-05
相关资源
最近更新 更多