如何使用`PARTITION BY`来简化此查询以查找最大总和?

huangapple go评论74阅读模式
英文:

how can i simplify this query using partition by to find max total?

问题

我想找到每个客户的最大交易数,并返回与该最大交易数相关联的店铺 ID。以下是我的查询集,它可以实现我的需求,但我希望找到一个更简单的解决方案。

使用以下代码查询:

WITH base AS (
  SELECT 
    shop_id, 
    customer_id, 
    sum(no_trans) AS total 
  FROM 
    tx.table 
  WHERE region = 'USA' 
  GROUP BY 1, 2
), 
cte2 AS (
  SELECT 
    shop_id, 
    customer_id, 
    total, 
    ROW_NUMBER() OVER (
      PARTITION BY customer_id 
      ORDER BY total DESC
    ) AS rank FROM base
), 
max_shop AS (SELECT * FROM cte2 WHERE rank = 1)

cte2 的输出如下:

shop_id | customer_id | total | rank
1234    | 100         | 6789  | 1
345     | 100         | 365   | 2
673     | 100         | 10    | 3

我希望只返回排名第一的行,即 rank = 1,就像在我的 max_shop CTE 中一样。对我来说,上面的查询似乎有点冗长,是否有更有效的方法可以实现这个需求?

英文:

I'd like to find the max number of transactions per customer by returning the shop_id associated with that max. Below is my set of queries that gives me what i want but i am hoping to find a simpler solution.

WITH base AS (
  SELECT 
    shop_id, 
    customer_id, 
    sum(no_trans) AS total 
  FROM 
    tx.table 
  WHERE region = 'USA' 
  GROUP BY 1, 2
), 
cte2 AS (
  SELECT 
    shop_id, 
    customer_id, 
    total, 
    ROW_NUMBER() OVER (
      PARTITION BY customer_id 
      ORDER BY total DESC
    ) AS rank FROM base
), 
max_shop AS (SELECT * FROM cte2 WHERE rank = 1)

The output of cte2 looks like:

shop_id	| customer_id|total |rank
1234	| 100	     |6789	|1
345	    | 100	     |365	|2
673	    | 100	     |10	|3

and i would like only the top row returned hence rank =1 as in my max_shop cte. the above to me seems a bit long - is there a more efficient way of doing this?

答案1

得分: 1

由于分析函数是在聚合之后评估的,您可以将basecte2合并在一起。

例如,

WITH tx_table AS (
  select '1234' shop_id, '100' customer_id, 6789 no_trans union all
  select '345' shop_id, '100' customer_id, 365 no_trans union all
  select '673' shop_id, '100' customer_id, 10 no_trans
),
cte2 AS (
  SELECT shop_id, 
         customer_id, 
         sum(no_trans) AS total,
         row_number() OVER (partition by customer_id order by sum(no_trans) desc) AS rn
    FROM tx_table
   GROUP BY shop_id, customer_id
) 
SELECT * FROM cte2 WHERE rn = 1;

查询结果

如何使用`PARTITION BY`来简化此查询以查找最大总和?

英文:

Since an analytic function is evaluated later after an aggregation, you can merge base and cte2 together.

For example,

WITH tx_table AS (
  select '1234' shop_id, '100' customer_id, 6789 no_trans union all
  select '345' shop_id,  '100' customer_id, 365 no_trans union all
  select '673' shop_id,  '100' customer_id, 10 no_trans
),
cte2 AS (
  SELECT shop_id, 
         customer_id, 
         sum(no_trans) AS total,
         row_number() OVER (partition by customer_id order by sum(no_trans) desc) AS rn
    FROM tx_table
   GROUP BY shop_id, customer_id
) 
SELECT * FROM cte2 WHERE rn = 1;

Query results

如何使用`PARTITION BY`来简化此查询以查找最大总和?

huangapple
  • 本文由 发表于 2023年3月7日 19:14:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75661268.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定