Функциональность обмена сообщениями Создание запроса SQL и представления базы данных - PullRequest
2 голосов
/ 08 июля 2011

Учитывая следующее:

enter image description here

Мне нужно иметь возможность получить список всех потоков, в которых принимал участие данный пользователь, отсортированных сначала по самому последнему сообщению, сотображается только самое последнее сообщение (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;

Вот как это работает.a Loginid 1 отправляет LoginId 2 сообщение:

  1. , создается новая тема и запись вставляется в MessageThread
  2. , новая запись добавляется в таблицу сообщений с указанным treadId сверху.
  3. ДВА записи вставляются в MessageThreadParticipant (LoginId отправителя и LogiId получателя)

    Когда пользователь открывает свой список сообщений, MessageReadState обновляет ReadDate сообщения.

ВОПРОС: Я хотел бы создать представление, где я мог бы просто фильтровать по LoginId (я бы использовал LINQ).Однако я не могу сделать это с помощью запроса выше (так как мне нужно было бы передать loginId где-то в инструкции SQL).Есть ли способ изменить вышеуказанный 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;

1 Ответ

2 голосов
/ 08 июля 2011

Делает ли это что-то вроде того, что вы хотите?

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...