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

时间:2015-02-02 00:09:53

标签: sql sql-server-2012

我是使用MS SQL 2012的新手,我正在尝试创建一个查询:

  1. 报告订单ID,订单日期和处理订单的员工ID

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

  3. 这是我提出的代码,但它返回特定订单日期的运费。而我正试图在特定订单之前从所有订单中获得最大运费。

    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 
    

3 个答案:

答案 0 :(得分:0)

目前还不清楚为什么要使用t3。从问题来看,这听起来并不像员工最近的订单日期是相关的,除非我误解(这绝对是可能的)。

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

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

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前面。我还包括一个左外连接,因为您的上一个查询与内连接将排除员工没有先前订单的任何行(即首次订单)。

答案 1 :(得分:0)

您可以使用相关子查询或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;

答案 2 :(得分:0)

第一步是阅读订单:

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  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;

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

相关问题