【发布时间】:2010-10-11 14:55:04
【问题描述】:
我一遍又一遍地使用相同的 SQL 模式,而且我知道必须有更好的方法,但我无法将它们拼凑在一起。这是该模式的一个简单版本,我在其中提取学生的信息和他们检查的最后一本书(如果存在):
SELECT TStudents.*,
BookName = (SELECT TOP 1 BookName
FROM TBookCheckouts
WHERE StudentID = TStudents.ID
ORDER BY DateCheckedOut DESC),
BookAuthor = (SELECT TOP 1 BookAuthor
FROM TBookCheckouts
WHERE StudentID = TStudents.ID
ORDER BY DateCheckedOut DESC),
BookCheckout = (SELECT TOP 1 DateCheckedOut
FROM TBookCheckouts
WHERE StudentID = TStudents.ID
ORDER BY DateCheckedOut DESC)
FROM TStudents
(为了这个例子,请忽略 TBookCheckouts 可能应该分为 TCheckouts 和 TBooks 的事实)
我要说明的是:我倾向于对同一个表中的列有很多子查询。我还倾向于需要按日期对这些子查询表进行排序以获取最新记录,因此它不像执行 LEFT JOIN 那样简单(至少对我而言)。但是请注意,除了返回哪个字段之外,我基本上是在执行相同的子查询 3 次。 SQL Server 可能足够聪明,可以优化它,但我不这么认为(我肯定需要更好地阅读执行计划......)。
虽然以这种方式构建它可能有优势(有时这最终会更具可读性,如果我有大量的子查询和子表),但这似乎并不是特别有效。
我已经研究过从派生表中进行 LEFT JOIN,可能包含 ROW_NUMBER() 和 PARTITION BY,但我似乎无法将它们拼凑在一起。
【问题讨论】:
-
如果多本书在同一天借阅怎么办?有决胜局的情况吗?
-
@LittleBobbyTables 好问题。幸运的是这不是一个真实的场景,所以我不必真正考虑这个哈哈。在我的真实场景中,我通常只是获取最新的资源,如果同一日期有两个,那要么是其他地方的错误,要么我不在乎。
标签: sql sql-server tsql subquery