【问题标题】:Getting Latest/Top orderID for each customer in SQL Server获取 SQL Server 中每个客户的最新/最高订单 ID
【发布时间】:2015-05-31 13:09:03
【问题描述】:

我有一个记录所有客户订单的数据库。我要做的不是获取每个客户的所有订单,而是获取客户与我们的最新订单。我已经通过使用 Sub-Select 语句来做到这一点,但是由于有多少数据,检索需要很长时间。所以我想知道是否有另一种方法可以加快速度?

这是我编写的使用 Sub-Select 语句的代码:

SELECT  Customer.CustomerId,
        Customer.Firstname + ' ' + Customer.Surname AS [Customer Name],
        (SELECT TOP(1) Orders.OrderId
        FROM Orders
        WHERE Orders.CustomerId = Customer.CustomerId
        ORDER BY Orders.OrderId DESC),
        (SELECT TOP(1) Orders.Item
        FROM Orders
        WHERE Orders.CustomerId = Customer.CustomerId
        ORDER BY Orders.OrderId DESC)
FROM Customer

任何有关如何改进此功能的帮助或信息将不胜感激。

谢谢

【问题讨论】:

  • ...为什么客户甚至会有一个订单 ID 列?
  • 抱歉更正了 - 有客户 ID 的是订单表

标签: sql sql-server


【解决方案1】:
  1. 如果创建了索引,则重建/刷新索引,这将有助于提高查询性能。

  2. 尝试创建非聚集索引,这将加快查询的执行速度。

【讨论】:

    【解决方案2】:

    可能对你有帮助

    WITH cte AS (
        SELECT c.CustomerName, 
               c.OrderID, 
               ROW_NUMBER() OVER(PARTITION BY c.CustomerName 
                                     ORDER BY c.CustomerName  DESC) AS rk
          FROM Customers c
          join Orders j c.OrderID = j.OrderId
          )
    SELECT a.*
      FROM cte a
     WHERE a.rk = 1
    

    【讨论】:

      【解决方案3】:

      有时使用 row_number 会得到更好的结果,因此您可以尝试以下方法:

      select * from (
        SELECT
          C.CustomerId,
          C.Firstname + ' ' + C.Surname AS [Customer Name],
          O.OrderId,
          O.Item,
          row_number() over (partition by O.CustomerId order by O.OrderId desc) as RN
        FROM
          Customer C
          join Orders O on O.CustomerId = O.CustomerId
      ) X
      where RN = 1
      

      如果有很多订单和客户,这也可能会很慢,因为没有搜索条件。您还应该检查索引,尤其是 Orders.CustomerId。

      没试过,所以希望没有语法错误:)

      【讨论】:

        【解决方案4】:

        试试这个:

        SELECT T1.CustomerID,T1.OrderID,T2.OrderItem
        FROM
           (SELECT C.CustomerID,MAX(O.OrderID) as OrderID
            FROM Customer C JOIN 
              Orders O ON C.CustomerID=O.CustomerID
            GROUP BY C.CustomerID) T1 
            JOIN
           (SELECT OrderID,Item
            FROM Orders) T2 ON T1.OrderID=T2.OrderID
        

        SQL Fiddle 中的示例结果。

        【讨论】:

        • 嗯...介意我问为什么是 max() 而不是 Top()?谢谢
        • @Danny:MAX 有点快,因为它使用Stream Aggregation。对于Order by,需要先对表数据进行排序,然后才能找到最耗时的记录。
        • 感谢您的信息。如果是这样,那我们不应该一直使用 MAX 而不是 TOP 吗??
        • @Danny:考虑这样一个场景:如果我们想选择一个薪水最高的员工的所有详细信息,我们不能使用 MAX(除非我们使用 join)。因为,我们将不得不使用GROUP BY,它当然会检索不止一行。所以在这种情况下,我们可以使用TOP
        猜你喜欢
        • 2014-12-11
        • 2023-01-21
        • 1970-01-01
        • 1970-01-01
        • 2013-11-08
        • 2010-09-24
        • 2019-07-01
        • 1970-01-01
        • 2021-11-12
        相关资源
        最近更新 更多