【问题标题】:select the sum of every client's last order选择每个客户最后一个订单的总和
【发布时间】:2011-05-02 10:23:16
【问题描述】:

我的数据如下:

ORDER_ID   CLIENT_ID   DATE     VALUE
        1881    51  2010-07-19  100.17
        1882    50  2010-07-19  100.17
        2754    50  2010-07-25  135.27
        2756    50  2010-07-25  100.28
        5514    50  2010-07-27  121.76
        5515    50  2010-07-28  109.59
        5516    50  2010-07-27  135.29
        5517    50  2010-07-28  121.77
        5518    50  2010-07-31  123.15
        5519    50  2010-07-31  123.16
        5520    50  2010-07-31  109.62
        6079    51  2010-07-31  100.33
        7372    50  2010-07-25  100.27

我想要的是指定一个初始日期,例如“2010-07-27”,以便在 WHERE 子句中仅过滤该日期或之后的记录;查询应该从客户端 50(订单 1881)和客户端 51(订单 5516)获取最新订单并将它们加在一起。我知道这很简单,我尝试了一些不同的方式,但找不到正确的路径。我想我今天的想法很狭窄,所以我向你寻求帮助。

谢谢。

【问题讨论】:

  • 我非常感谢您的每一个回答,并希望对您的帮助表示衷心的感谢。谢谢。

标签: sql sql-server sql-server-2005 group-by sum


【解决方案1】:

我宁愿不使用子查询,因为随着表变大,它们会减慢查询速度...

这个怎么样:

SELECT SUM(VALUE) AS SumOfOrderValues
FROM
    YourTable t 
    INNER JOIN (
        SELECT CLIENT_ID, MAX(ORDER_ID) AS MaxOrderId
        FROM YourTable
        WHERE [DATE] >= '2010-07-27'
        GROUP BY CLIENT_ID
    ) AS m ON m.MaxOrderId = t.ORDER_ID

这应该会在某个日期或之后为您提供每个客户的最新订单。然后是特定订单的值的总和。

【讨论】:

  • +1 欢迎来到 SO。如果您认为子查询很慢,请阅读执行计划;大多数not exist 子句实际上就像是连接一样运行。
  • 谢谢 Andomar,我在看到 wllmsaccnt 的解决方案后提到了子查询。
【解决方案2】:

为什么是 1881 和 5516 ?我认为这 2 个客户的最后一个订单是 5520 和 6079。 下面是我的: 从中选择总和(值)( 选择值,row_number() over (partition by client_id order by order_id desc) as sn 从 表名,其中日期 > '2010-7-27' ) T 其中 sn = 1

【讨论】:

  • 客户 51 有 2 个订单:1881 和 6079。但只有 1881 在日期“2010-07-27”之前。客户端 50 也是如此
  • 把 你会得到你需要的。我想我误读了你的问题..
【解决方案3】:
SELECT

SUM
(
  (SELECT TOP(1) VALUE
   FROM ORDER
   WHERE
   CLIENT_ID=C.CLIENT_ID
   DATE >= @LBOUND_ORDER_DATE
   ORDER BY DATE DESC
  )
) AS TotalLatestOrders

FROM

CLIENT C

【讨论】:

  • 很好,但它只返回第一个客户 (CLIENT_ID = 50) 的最后一个订单 (ORDER_ID = 5516)。在这种情况下,我必须获取每个客户的最后一个订单(50、51...)
  • 对相关子程序求和。它应该只返回一个值,该值是每个客户最近订单的值的总和。
【解决方案4】:

让我们试一试:

SELECT CLIENT_ID, SUM(VALUE)
FROM YourTable
WHERE DATE >= '7/27/2010'
GROUP BY CLIENT_ID

除非我误读或误解了您的问题。 :)

编辑:让我们试试这个,给出反馈:

SELECT SUM(VALUE)
FROM MyTable mt,
(SELECT CLIENT_ID, MAX([DATE]) AS 'Date'
FROM MyTable
GROUP BY CLIENT_ID) AS r
WHERE mt.CLIENT_ID = r.CLIENT_ID
AND mt.DATE = r.Date

再次编辑:基于 ORDER_ID 而不是 DATE 的最后一个订单:

SELECT SUM(VALUE)
FROM MyTable mt,
(SELECT CLIENT_ID, MAX([ORDER_ID]) AS 'ORDER_ID'
FROM MyTable
GROUP BY CLIENT_ID) AS r
WHERE mt.CLIENT_ID = r.CLIENT_ID
AND mt.ORDER_ID = r.ORDER_ID

【讨论】:

  • 对不起,我不清楚。您的查询给了我每个客户的最后订单。我想把每一个最后的订单加在一起。
  • 对不起,Lynx,我已经用应该工作的方法更新了答案(在本地重新创建表和数据时)。请告诉我进展如何!
  • @JasonA: +1 作为对 SO 的欢迎 :) 我认为对于这个示例,您的查询仍然会汇总当天的所有订单(5518、5519、5520)
  • 它将订单 5515、5517、5518、5519、5520、6079 中的所有值相加。
  • 其实就是 5515,5517,5518,5519,5520 和 6079 = (
【解决方案5】:

您可以使用子查询来过滤不存在​​后续订单的订单,例如:

select  sum(t1.value)
from    YourTable t1
where   t1.Client_ID in (50, 51)
        and t1.Date > '2010-07-27'
        and not exists
        (
        select  *
        from    YourTable t2
        where   t1.Client = t2.Client
                and 
                (
                    t1.Date < t2.Date
                    or
                    (t1.Date = t2.Date and t1.Order_ID < t2.Order_ID)
                )
        )

如果只选择总和,则不需要group by

您的评论表明您正在寻找 2010 年 7 月 27 日之后的第一个(不是最新的)订单。如果是这种情况,请将子查询条件替换为:

                (
                    t1.Date > t2.Date
                    or
                    (t1.Date = t2.Date and t1.Order_ID > t2.Order_ID)
                )

【讨论】:

  • 谢谢,但是这个总和的结果不是预期的。使用 ORDER_ID 而不是 sum() 函数,我看到该函数对订单 5518、5519、5520 和 6079 求和 - 它应该只对订单 5516 和 1881 求和。在 AND NOT EXISTS 之前一切都很好。
  • @Lynx Kepler:编辑:现在如果有多个相同日期的订单,它会选择订单号最高的那个。 not exists 用于过滤最新订单;如果您想汇总 2010-07-27 之后的所有订单,请忽略整个条款。
猜你喜欢
  • 1970-01-01
  • 2010-12-08
  • 2013-02-16
  • 1970-01-01
  • 2021-02-23
  • 1970-01-01
  • 2017-07-08
  • 2011-03-13
  • 2010-09-24
相关资源
最近更新 更多