kac*_*apy 7 sql-server-2005 query
我有一个电子邮件类型的应用程序,想为用户选择所有消息(收件箱)。问题是我将电子邮件的标题部分规范化到数据库中,这样平面数据就会进入消息表,而从、到、抄送、密件抄送则存储到另一个表中。
根据 PK/ FK 关系。
我非常重视的一件事是 SQL 解决方案的效率,因为这将是多次执行的代码,并且可能是整个数据库中运行次数最多的 sql
这里的上下文是我的数据库模式的视图。
这就是我要做的。我经常使用 Coalesce 将行放入分隔的字段中,它总是能很好地执行和扩展(只要您意识到子查询总是会导致一些性能下降)。
如果您不喜欢将它作为存储过程运行,您也可以轻松地将其重写为表值函数。
我想另一种方法是 CTE,但我对这种从头开始打字的方法并不熟悉。
CREATE PROCEDURE GetMessageById
@pMessageID int
AS
BEGIN
SET NOCOUNT ON;
Declare @pTo varchar(max)
Declare @pCC varchar(max)
Declare @pBC varchar(max)
SELECT @pTo = COALESCE(@pTo + ', ', '') + [EmailAddress]
FROM MessageRecipient
WHERE MessageID = @pMessageID AND RecipientTypeID = 1 /** or whatever the id of TO field is */
SELECT @pCC = COALESCE(@pCC + ', ', '') + [EmailAddress]
FROM MessageRecipient
WHERE MessageID = @pMessageID AND RecipientTypeID = 2 /** or whatever the id of CC field is */
SELECT @pBC = COALESCE(@pBC + ', ', '') + [EmailAddress]
FROM MessageRecipient
WHERE MessageID = @pMessageID AND RecipientTypeID = 3 /** or whatever the id of BCC field is */
SELECT Message.*, @pTo as [ToField], @pCC as [CCField], @pBC as [BCCField], (SELECT TOP 1 [EmailAddress] FROM MessageRecipient Where RecipientTypeID = 0 /**<sender id>*/ AND MessageID = @pmessageID) AS [FromField] FROM Message Where Message.ID = @pMessageID
END
GO
Run Code Online (Sandbox Code Playgroud)
您可能会问自己,以这种方式使用 Coalesce 时是如何工作的(我第一次看到它使用时确实如此)。基本上它创建一个递归查询,依次返回集合中的每个后续非空值,直到返回集合结束。从另一端出来,您会得到一个以昏迷分隔的所有结果列表作为单个字符串。
我将创建一个名为viewInbox的视图,该视图由所有一对一关系表设计。这将是我的主要查询视图。我会使用这个视图 (viewInbox) 来显示所有收件箱项目的列表。
当用户向下钻取到消息,然后,我会带回所有包括信息一到许多从多到的,CC的和BCC的关系。