【发布时间】:2012-03-27 14:55:30
【问题描述】:
为了简化描述,我将使用成员表和邮件表。邮件表的结构如下:
-------------------------------
FromMember int NOT NULL (FK)
ToMember int NOT NULL (FK)
...
-------------------------------
我想编写一个查询,它将返回特定成员的所有邮件,无论他是 FromMember 还是 ToMember。这很容易,只需在 WHERE 子句中使用 OR 子句。
但复杂之处在于我想将邮件表加入成员表以检索 other 成员的成员信息。因此,如果我是 FromMember,则成员表的联接子句将使用 ToMember 字段,如果我是 ToMember,则联接子句将使用 FromMember 字段。基本上,ON 子句需要根据特定条件加入两个不同的字段。这可能吗?
到目前为止,我的解决方案是使用 UNION ALL,如下所示:
SELECT * FROM mail INNER JOIN member ON mail.ToMember = member.MemberID
WHERE mail.FromMember = @me
UNION ALL
SELECT * FROM mail INNER JOIN member ON mail.FromMember = member.MemberID
WHERE mail.ToMember = @me
但是,我想将此查询放在视图中,因为结果集将在我的代码中的许多地方使用。这意味着我需要一个参数化视图,我认为我需要使用用户定义的表函数来实现它。
基本上,我正在寻找两个答案:
有没有更好的方法来编写该查询而不是 UNION ALL?
我应该将该查询放在 VIEW 还是 UDF 中?
如果 VIEW 是首选方法,我如何将 @me 参数传递给 VIEW。我无法将@me 参数移至 WHERE 子句,有些人在他们的回答中说过,因为 WHERE 子句取决于 ON 子句。取出 WHERE 子句然后对它们进行 ORing 将不会返回与上述 UNION ALL 查询相同的结果集。
【问题讨论】:
-
您可以创建一个包含 UNION ALL 的视图。为什么不呢?
-
请注意人们在他们的解决方案中建议使用“OR”:您不会使用任何索引,而是会扫描整个表。这可能会变得很痛苦,具体取决于行数和/或此查询运行的次数。使用
UNION将允许在FromMember和ToMember上命中索引(前提是它们存在)。根据我的经验,在大多数情况下,使用索引会比表扫描快得多。 -
@KM:上面的“OR”语句是否也适用于 INNER JOIN ON 子句中的 OR 子句?正如@quzary 在下面的答案中指定的那样?
-
没关系。这样想你有一个很大的电话簿(数千页)并且你想找到一个特定的名字。您只需查找名称,即可快速获得。现在,假设您想在“名称”或“地址”字段中查找特定名称。你是怎样做的?查看每个条目,这是一个表扫描。现在假设您有两个电话簿,一个按名称排序,一个按地址排序。您可以使用联合方法:在“名称”排序的书中快速搜索。您将这些结果附加到快速搜索“地址”排序书的结果中。
-
记住 SQL 的目标是快速结果,也就是索引使用。你经常不得不编写重复的代码(想想复制粘贴)。如果您优化 SQL 以实现高效的击键,通常会降低执行速度。
标签: sql-server database foreign-keys relational-database