如何使用聚合添加组中的最新订单项?

时间:2016-01-21 19:29:36

标签: sql sql-server join

嘿stackoverflow社区,

我有一张Sales表,下面是假设。

Customer       Revenue       State      Date
David          $100          NY         2016-01-01
David          $500          NJ         2016-01-03
Fred           $200          CA         2016-01-01
Fred           $200          CA         2016-01-02

我正在撰写一份关于客户产生的收入的简单查询。输出返回如下:

David     $600
Fred      $400

我现在要做的是添加最新购买日期的行以及与最新购买相关联的州。

期望的结果:

David     $600      2016-01-03        NJ
Fred      $400      2016-01-02        CA

我想尽可能保持SQL代码的清洁。我还想避免对新查询进行JOIN,因为此查询可能开始变得复杂。关于如何做的任何想法?

4 个答案:

答案 0 :(得分:1)

您可以使用row_number()(或first_value())和条件聚合:

执行此操作
select customer, sum(revenue), max(date),
       max(case when seqnum = 1 then state end) as mostRecentState
from (select s.*,
             row_number() over (partition by customer order by date desc) as seqnum
      from s
     ) s
group by customer;

答案 1 :(得分:0)

Hy,试试这个:

SELECT
   S.CUSTOMER
  ,S.TOTAL
  ,M.DT
  ,M.STATE
FROM
(
  --SUM
  SELECT
     CUSTOMER
    ,SUM(REVENUE) AS TOTAL
  FROM TB
  GROUP BY
    CUSTOMER
) S 
INNER JOIN (
        --MAX DATE
        SELECT
          CUSTOMER
          ,STATE
          ,DT
       FROM TB
       WHERE (CUSTOMER, DT) IN (
                              SELECT AUX.CUSTOMER ,MAX(AUX.DT)  
                              FROM TB AUX 
                              GROUP BY AUX.CUSTOMER
                            )
) M ON (S.CUSTOMER = M.CUSTOMER );

答案 2 :(得分:0)

SELECT Customer
  , (SELECT SUM(Revenue) FROM #t WHERE Customer = xx.Customer ) AS TotalRevenue
  , Dt, STATE
FROM #t xx
WHERE Dt = (SELECT MAX(Dt) FROM #t WHERE Customer = xx.Customer)
ORDER BY Customer

答案 3 :(得分:0)

在大型数据集上,由于性能问题,我会避免使用ROW_NUMBER()函数。以下是我过去如何做到这一点并获得良好绩效结果的示例:

SELECT DISTINCT
    t.customer,
    totals.totalRevenue,
    t.state,
    t.date
FROM
    @test AS t INNER JOIN (
        SELECT
            customer,
            SUM(revenue) AS totalRevenue,
            MAX(date) AS maxDate
        FROM
            @test AS tSub
        GROUP BY
            customer
    ) AS totals ON t.customer = totals.customer AND t.date = totals.maxDate

如果客户和日期字段对于每条记录都是唯一的,则可以删除顶部的DISTINCT子句。

在执行查询之前尝试SET STATISTICS IO ONSET STATISTICS TIME ON - 较少的逻辑磁盘IO通常意味着更好的性能。