【问题标题】:how to use group by with min() function如何通过 min() 函数使用 group by
【发布时间】:2022-01-03 11:09:16
【问题描述】:

我正在尝试编写一个查询,根据总付款、付款方式、姓名和电话号码为我提供最短订单日期和分组 除了客户名称来自不同的表之外,所有都来自同一个表。

我面临的问题是,因为我使用的是 min(date),所以我应该使用 group by,因为每个订单都有不同的 id,所以它会给我相同的订单,因为有每个订单没有最低日期!我仍然会有重复的记录。

我的查询是这样的:

SELECT order_id, total_paid, payment_method, c.name, phone, min(date) FROM orders
LEFT JOIN customers c 
GROUP BY total_paid, payment_method, c.name, phone, order_id

【问题讨论】:

  • 是 MySQL 还是 Snowflake?
  • 问题翻译不好请通过添加示例数据和预期输出为文本来澄清
  • @GokhanAtil 雪花
  • 谢谢,我更新了你帖子的标签。你检查过Koushik的反应吗?您需要使用子查询,但我认为您需要重新考虑您的分组列。

标签: sql database snowflake-cloud-data-platform


【解决方案1】:

您已接近,但需要再执行一步。
使用子查询,您可以按总付款、付款方式、姓名和电话号码计算最小订单日期和分组,并返回主表以获取预期数据。


SELECT order_id, total_paid, payment_method, c.name, phone, min(date) FROM orders
LEFT JOIN customers c on c.id = customer_id --I assumed.
JOIN 
(SELECT total_paid tpaid, payment_method pmethod, c.name name, phone ph, min(date) mindate FROM orders
LEFT JOIN customers c  on c.id = customer_id --I assumed.
GROUP BY total_paid, payment_method, c.name, phone ) subq  -- this is calculating data for min date. 
ON subq.tpaid=total_paid  and subq.pmethod=payment_method  and subq.name=c.name and subq.ph=phone and subq.mindate =date 

【讨论】:

    【解决方案2】:

    如果您想获得日期最短的 ROW(针对 customer_id),那么 QUALIFYROW_NUMBER 可以为您提供帮助:

    SELECT 
       o.order_id, 
       o.total_paid, 
       o.payment_method, 
       c.name, 
       o.phone,
       o.date
    FROM orders AS o
    LEFT JOIN customers c
        ON o.customer_id = c.id  
    QUALIFY ROW_NUMBER() OVER (PARTITION BY o.customer_id ORDER BY O.date) == 1
    

    但这似乎不像你问的那样。

    我在内部无法从ordrerscustomers 中找到您试图回答的问题,该问题按总付费分组。其中,将每位客户支付的总费用相加是有道理的,但是使用min(date) 没有问题。这就是为什么我选择 QUALIFY 的原因,因为它似乎不想从聚合的角度进行分组,但你想限制,因此 ROW_NUMBER 对结果进行排序/排名,QUALIY 避免需要做子选择过滤器,看起来像:

    SELECT 
       order_id, 
       total_paid, 
       payment_method, 
       name, 
       phone,
       date
    FROM (
        SELECT 
           o.order_id, 
           o.total_paid, 
           o.payment_method, 
           c.name, 
           o.phone,
           o.date
           ROW_NUMBER() OVER (PARTITION BY o.customer_id ORDER BY O.date) AS rn
        FROM orders AS o
        LEFT JOIN customers c
            ON o.customer_id = c.id  
    )
    WHERE rn = 1
    

    但这也表明,如果您的订单/客户像猜测的那样加入,则不需要在子选择中进行加入,当处理非常大的数据集时,这是尽可能晚做的重要事情.因此,真的应该这样写:

    SELECT 
       o.order_id, 
       o.total_paid, 
       o.payment_method, 
       c.name, 
       o.phone,
       o.date
    FROM (
        SELECT 
           order_id, 
           total_paid, 
           payment_method, 
           phone,
           date
           ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY date) AS rn
        FROM orders
    ) AS o
    LEFT JOIN customers c
        ON o.customer_id = c.id  
    WHERE rn = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-07
      • 2020-02-02
      • 1970-01-01
      • 2013-04-06
      • 2019-08-15
      • 2013-05-19
      • 2017-05-24
      • 1970-01-01
      相关资源
      最近更新 更多