SQLServer从子查询中获取前1行

时间:2014-11-24 16:22:16

标签: sql sql-server sql-server-2008

在一个巨大的产品查询中,我试图获得每个元素的最后购买价格。在我的第一种方法中,我在购买表上添加了一个子查询,按日期后代排序,只获得第一行,所以我确保我得到了最新的一行。但它没有表现出任何价值。 现在我再次看到它,这是合乎逻辑的,因为子查询仍然没有对产品的限制然后列出所有购买并获得最新的购买,而不必是当前正在处理的产品主要查询。所以什么都不回报。

这是非常简化的代码:

SELECT P.ID, P.Description, P... blah, blah
FROM Products
LEFT JOIN (
    SELECT TOP 1 B.Product,B.Date,B.Price --Can't take out TOP 1 if ORDER BY
    FROM Buys B
    --WHERE... Can't select by P.Product because doesn't exist in that context
    ORDER BY B.Date DESC, B.ID DESC
) BUY ON BUY.Product=P.ID
WHERE (Some product family and kind restrictions, etc, so it processes a big amount of products)

我在主要的选择stmt中考虑了一个嵌入式查询,但是由于我需要多个值,因此它意味着对每个值进行查询,这很丑陋。

有没有办法做到这一点并避免臭名昭着的LOOP?谁知道好的?

2 个答案:

答案 0 :(得分:9)

你正走在使用outer apply的道路上,所以让我们继续:

SELECT P.ID, P.Description, P... blah, blah
FROM Products p OUTER APPLY
     (SELECT TOP 1 B.Product,B.Date,B.Price --Can't take out TOP 1 if ORDER BY
      FROM Buys b
    --WHERE... Can't select by P.Product because doesn't exist in that context
      WHERE b.Product = P.ID
      ORDER BY B.Date DESC, B.ID DESC
     ) buy
WHERE (Some product family and kind restrictions, etc, so it processes a big amount of products)

在此上下文中,您可以apply作为可以返回多列的相关子查询。在其他数据库中,这称为“横向连接”。

答案 1 :(得分:2)

似乎是OUTER APPLY的好候选人。你需要这些东西......

SELECT P.ID, P.Description, P... blah, blah
FROM Products P
OUTER APPLY (
    SELECT TOP 1 B.Product,B.Date,B.Price 
    FROM Buys B
    WHERE B.ProductID = P.ID
    ORDER BY B.Date DESC, B.ID DESC
) a