在给定日期之前获得最大值

Getting max value before given date

我对使用 MS SQL 2012 还很陌生,我正在尝试创建一个查询:

  1. 报告订单id、订单日期和处理订单的员工id

  2. 报告同一员工在该订单之前处理的订单中的最高运费

这是我想出的代码,但它 returns 是特定订单日期的运费。而我试图从特定订单之前的所有订单中获得最大运费。

select o.employeeid, o.orderid, o.orderdate, t2.maxfreight
from orders o
inner join
(
    select employeeid, orderdate, max(freight) as maxfreight
    from orders
    group by EmployeeID, OrderDate
) t2
on o.EmployeeID = t2.EmployeeID
inner join
(
    select employeeid, max(orderdate) as mostRecentOrderDate
    from Orders
    group by EmployeeID
) t3
on t2.EmployeeID = t3.EmployeeID
where o.freight = t2.maxfreight and t2.orderdate < t3.mostRecentOrderDate 

不清楚您为什么要使用 t3。从这个问题来看,员工最近的订单日期听起来根本不相关,除非我误会了(这绝对有可能)。

我认为问题在于 t2。您正在按订单日期分组,如您所述,这将 return 该日期和员工 ID 的最大运费。您需要计算订单发生日期之前发生的所有订单的最大总数,对于该员工,对于您正在 returning 的每一行。

为此使用子查询可能更有意义。

SELECT o.employeeid, o.orderid, o.orderdate, m.maxfreight
FROM 
    orders o LEFT OUTER JOIN
    (SELECT max(freight) as maxfreight 
    FROM orders AS f
    WHERE f.orderdate <= o.orderdate AND f.employeeid = o.employeeid
) AS m

希望这在语法上是正确的,因为我现在不在 SSMS 面前。我还包括一个左外连接,因为您之前使用内连接的查询会排除员工没有之前订单(即有史以来的第一个订单)的任何行。

您可以使用相关子查询或 apply 做您想做的事。这是一种方法:

select o.employeeid, o.orderid, o.orderdate, t2.maxfreight
from orders o outer apply
     (select max(freight) as maxfreight
      from orders o2
      where o2.employeeid = o.employeid and
            o2.orderdate < o.orderdate
     ) t2;

在 SQL Server 2012+ 中,您还可以使用累积最大值来执行此操作:

select o.employeeid, o.orderid, o.orderdate,
       max(freight) over (partition by employeeid
                          order by o.orderdate rows between unbounded preceding and 1 preceding
                         ) as maxfreight
from orders o;

第一步是阅读订单:

select o.employeeid, o.orderid, o.orderdate
from   orders o
where  o.orderid = @ParticularOrder;

这为您提供了外出获取同一员工之前的订单并将每个订单加入您从上面获得的行所需的一切。

select  o.employeeid, o.orderid, o.orderdate, o2.freight
from    orders o
join    orders o2
    on  o2.employeeid = o.employeeid
    and o2.orderdate < o.orderdate
where   o.orderid = @ParticularOrder;

现在你有一大堆行,前三个值相同,第四个是每个先前订单的运费。因此,只需按前三个字段和 select 先前订单的最大值进行分组。

select  o.employeeid, o.orderid, o.orderdate, max( o2.freight ) as maxfreight
from    orders o
join    orders o2
    on  o2.employeeid = o.employeeid
    and o2.orderdate < o.orderdate
where   o.orderid = @ParticularOrder
group by o.employeeid, o.orderid, o.orderdate;

完成。分阶段构建您的查询,很多时候它会比您最初想象的要简单得多。