【问题标题】:SQL query returning customers which have spent over $15.000 in a timespan of 72 hoursSQL 查询在 72 小时内花费超过 15.000 美元的回头客
【发布时间】:2018-10-04 21:37:21
【问题描述】:

对于一个学校项目,我试图用 SQL 编写一个查询来检查订单表,如果有任何买家在 72 小时的时间跨度内花费超过 15.000 美元。

所以我的数据库包含一个订单表,每个订单包含一个唯一的买家名称、订单日期(OrderCreatedOn)和订单价格(金额)。通过我的 SQL 查询,我试图在 72 小时内单个客户的订单总和超过 15.000 美元时触发警报。

我想出了以下查询:

SELECT Orders.BuyerName, SUM(Amount) AS Total_Amount, Orders.OrderCreatedOn
FROM Orders 
WHERE OrderCreatedOn BETWEEN OrderCreatedOn AND DateADD(Hour, - 72 , 
GETDATE())
GROUP BY Orders.BuyerName, Orders.amount , Orders.OrderCreatedOn
HAVING SUM(Orders.Amount) > 15000
ORDER BY BuyerName DESC

WHERE 子句似乎无法正常工作,它只是返回 SUM 超过 15.000 的所有订单,我不知道如何解决。

任何帮助将不胜感激:),在此先感谢!

【问题讨论】:

  • WHERE OrderCreatedOn BETWEEN GETDATE() AND DateADD(Hour, - 72 , GETDATE())
  • 在预期的输出中为什么有OrderCreatedOn?这是第一顺序吗?最后一个?如果买家出现 2 次怎么办(想想 6 天内每天下订单,其中任何连续 3 天的总和超过过滤后的金额)。
  • 你快到了。使用@PM77-1 建议的内容,但不要忘记交换getdatedateadd 位置)实际上>= dateadd(-72) 就足够了 - 不需要上限。 Orders.amount , Orders.OrderCreatedOnGROUP BY 列表中不是必需的 - 它们阻止按 BuyerName 分组。

标签: sql sql-server sql-server-2017


【解决方案1】:

Where 子句似乎是这里的问题

WHERE OrderCreatedOn BETWEEN OrderCreatedOn AND DateADD(Hour, - 72 , 
GETDATE())

上述子句始终为真,因为OrderCreatedOn 将等于between 的第一部分(再次为OrderCreatedOn)。

您应该将where 子句修改为-

WHERE OrderCreatedOn >= DateADD(Hour, - 72 , GETDATE())

此外,如果同一买家在 72 小时内有多个订单,您的查询可能不起作用,因为您在 group byselect 中有 OrderCreatedOn 列,它将始终返回包含买家和订单日期组合的唯一记录。 Sum 仅适用于该订单。您还想在Amount 列上使用聚合函数,因此它不应该是“分组依据”的一部分。所以你应该从Group by 中删除OrderCreatedOnAmount,这将把买家在72 小时内下的所有订单和Sum 分组所有这些订单的数量。最终查询看起来像 -

SELECT Orders.BuyerName, SUM(Amount) AS Total_Amount
FROM Orders 
WHERE OrderCreatedOn >= DateADD(Hour, - 72 , GETDATE())
GROUP BY Orders.BuyerName 
HAVING SUM(Orders.Amount) > 15000
ORDER BY BuyerName DESC

【讨论】:

  • 非常感谢您的时间和明确的解释!我尝试了您的查询,但它没有返回任何结果,我认为这可能是因为订单的最新日期是 3 个月前(从 2018 年 7 月 13 日起)。因此,为了测试查询,我不得不遗憾地使用旧数据。是否有任何解决方法来测试这些较早日期的查询?
  • @Brenkheer 将 GETDATE() 替换为 '2018-07-14'?
  • 是的,正如@MatBailie 所说,将 GETDATE() 替换为您想视为今天的日期的任何日期,例如“2018-07-14”
  • 我认为这个答案是错误的,因为它考虑了一个单一的时间范围。如果您需要了解何时达到阈值,那么您需要按行汇总。投反对票。
【解决方案2】:

您可以使用表表达式来计算每一行的 72 小时累计支出。然后您可以对其进行查询以过滤所需的行:

select * from (
  select
      buyername,
      ordercreatedon,
      amount,
      (select sum(amount) from orders o2
         where o2.buyername = o.buyername 
           and o2.ordercreatedon between 
             dateadd(hour, -72, o.ordercreatedon) and o.ordercreatedon
      ) as acc
    from orders
  ) x
  where acc >= 15000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多