システム メッセージングをカバーする 2 つのテーブルを持つ SQL Server (2008 R2) を使用するシステムを継承しました。メッセージには 1 対多の関係があり、複数のユーザーに送信できます。
プライマリ テーブルの 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)
それが明確でない場合は、メッセージの作成者の従業員 ID を使用して新しいメッセージが Messaging テーブルに入れられ、新しい会話 ID が作成されます。次に、受信者ごとに X 行が MessagingDetails に挿入され、Messaging テーブルへの参照が返され、同じ会話 ID が使用されます。
新しい返信は同じように見え、返信メッセージは Messaging テーブルに入れられ、受信者の詳細は同じ会話 ID を使用して MessagingDetails に入れられるため、メッセージ スレッド全体を 1 つの番号で取得できます。
これは、自分が作成した、または自分に送信されたすべての未読メッセージの数を取得しようとすると、ずさんになります。システム内の他のユーザーによってログイン ユーザーに送信されたすべての未読メッセージを取得する既存のクエリを次に示します。最初にメッセージを作成した場所は次のとおりです。
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
私は同じテーブルに 2 回、1 回はそれ自体に参加する内部を嫌います。上記のスキーマを考えると、これらのクエリを記述するより良い方法はありますか?