在 SQL 连接中仅选择相关表中的第一行
数据库连接通常会从相关表中检索多个匹配的行。 本文解决了即使存在多个匹配项,您也需要将联接限制为每个父记录的单行的情况。 这可以防止查询输出中出现重复结果。
挑战
考虑两个表:Orders
和 LineItems
。 通常,一份订单有一个行项目,但有些订单可能有多个行项目。 显示订单详细信息时,每个订单仅显示一个订单项至关重要,否则会导致结果重复混乱。
最初的方法(及其失败)
在联接中使用 TOP 1
的天真尝试会直接失败,因为内部查询无法访问外部表的列(如 OrderID
)。
解决方案:交叉应用和内部连接
最有效的方法是使用 CROSS APPLY
(在 SQL Server 2005 及更高版本中可用)或针对旧版本的巧妙 INNER JOIN
。
使用 CROSS APPLY(SQL Server 2005 及更高版本)
CROSS APPLY
为外表中的每一行生成一个行集,从而启用相关子查询。 然后,该子查询从相关表中过滤并选择一行。
<code class="language-sql">SELECT Orders.OrderNumber, LineItems2.Quantity, LineItems2.Description FROM Orders CROSS APPLY ( SELECT TOP 1 LineItems.Quantity, LineItems.Description FROM LineItems WHERE LineItems.OrderID = Orders.OrderID ) LineItems2</code>
使用 INNER JOIN(SQL Server 2005 之前版本)
对于缺少 CROSS APPLY
的较旧 SQL Server 版本,带有子查询的 INNER JOIN
可获得相同的结果:
<code class="language-sql">SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description FROM Orders INNER JOIN LineItems ON LineItems.LineItemGUID = ( SELECT TOP 1 LineItemGUID FROM LineItems WHERE OrderID = Orders.OrderID )</code>
关于决定论的重要说明:
如果没有 TOP 1
子句,ORDER BY
子句本质上是不确定的。 为了保证结果一致(即始终选择 相同“第一个”行项目),请在内部查询中添加 ORDER BY
子句(例如 ORDER BY LineItems.SomeColumn
)。 这确保了订单项的可预测选择。
以上是如何在 SQL 中高效地仅连接到相关表的第一行?的详细内容。更多信息请关注PHP中文网其他相关文章!