【问题标题】:Execution orders of SQL aggregate functionsSQL聚合函数的执行顺序
【发布时间】:2021-12-25 15:42:34
【问题描述】:

我在 SQLite 中有一个销售表:

purchase_date units_sold customer_id
15 1 1
17 1 1
30 3 1

我想获得每个客户在购买的第一个日期和最后一个日期的总unit_solds。我的查询是:

  select customer_id,
         sum(units_sold) total_units_sold
    from sales
group by customer_id
  having purchase_date = min(purchase_date) 
      or purchase_date = max(purchase_date)

我期待这样的结果:

customer_id total_units_sold
1 4

但我得到了:

customer_id total_units_sold
1 5

我想知道为什么这个解决方案不起作用。

【问题讨论】:

  • 请只标记一个 DBMS,而不是四个不同的。
  • 请您分享您正在使用哪种类型的数据库,由于某种原因,不同的方言可能会以不同的方式处理您的查询,但我对此的想法是组中未指定have子句中的购买日期并且在技术上是一个“未知”。您需要在您的组中包含购买日期
  • 好的,谢谢。下次会小心的
  • have 子句发生在我认为的选定数据之后。因此,在您使用 having 子句过滤它之前,求和已经发生了。
  • 仅供参考,HAVING 子句可能无效,因为purchase_date 在功能上不依赖于GROUP BY 术语。 sqlite 可能无法检测到该问题。想想看。每个客户可以在不同的日期进行多次销售。 GROUP BY customer_id 不一定与purchase_date 相关联。 MAX(purchase_date)HAVING 子句中非常好,但不仅仅是purchase_dateHAVING 子句作用于组,而不是 sales 中的任何单个行。

标签: sql sqlite


【解决方案1】:

短语的顺序不正确 注意:having 语句在编译后执行。

您需要以部分查询的形式获取结果 比如我根据每个客户安排知道日期的第一行 以及日期的最后一行(通过在降序后获取第一行) 然后执行group语句

示例完成

      select customer_id,sum(units_sold) from (
         select customer_id, units_sold,purchase_date,
            ROW_NUMBER() over(partition by customer_id order by purchase_date) As RowDatefirst,
            ROW_NUMBER() over(partition by customer_id order by purchase_date desc)As RowDatelast    
         from sales
         ) t where t.RowDatefirst = 1 or t.RowDatelast=1
       group by customer_id

【讨论】:

  • 谢谢。我的印象是在选择之前执行了
【解决方案2】:

试试这个:

 SELECT a.customer_id, SUM(a.units_sold) as total_units_sold
FROM sales a
INNER JOIN (
       SELECT customer_id, MIN(purchase_date) as _first ,MAX(purchase_date) as _last
       FROM sales
       GROUP BY customer_id
) b ON a.customer_id = b.customer_id AND
      (a.purchase_date = b._first OR a.purchase_date = b._last)
GROUP BY a.customer_id

http://sqlfiddle.com/#!7/0a4a4/7

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 2017-04-21
    相关资源
    最近更新 更多