在表上聚合查询?

Posted

技术标签:

【中文标题】在表上聚合查询?【英文标题】:Aggregating query on Table? 【发布时间】:2017-10-17 15:24:59 【问题描述】:

我被困在一个点上,我必须从客户表中选择具有 customer_id 和 amount_paid 值的数据。我想以这样的形式显示结果,即用户的前 3 个值应该在列名组中作为文本 Group1 和该用户的 4 到 10 个值可见,以获取文本 Group2 和其余 Group3 。

您能告诉我如何对每个客户的值进行分组吗?

谢谢

【问题讨论】:

【参考方案1】:

我想以这样的形式显示结果,即用户的前 3 个值应该在列名组中作为文本 Group1 可见,并且该用户的 4 到 10 个值应该显示为文本 Group2 和其余 Group3

以下是 BigQuery 标准 SQL

#standardSQL
SELECT
  user_id, 
  CASE 
    WHEN pos BETWEEN 1 AND 3 THEN 1
    WHEN pos BETWEEN 4 AND 10 THEN 2
    ELSE 3
  END grp,
  SUM(amount_paid) amount_paid
FROM (
  SELECT 
    user_id, amount_paid, 
    ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY amount_paid DESC) pos
  FROM customer 
)
GROUP BY user_id, grp
-- ORDER BY user_id, grp   

您可以测试/玩下面的虚拟生成数据

#standardSQL
WITH users AS (
  SELECT user_id FROM UNNEST(GENERATE_ARRAY(1,5)) user_id
),
amounts AS (
  SELECT ROUND(50 * RAND()) amount_paid FROM UNNEST(GENERATE_ARRAY(1,50)) amount_paid
),
customer AS (
  SELECT user_id, ROUND(amount_paid * RAND()) amount_paid  
  FROM users
  CROSS JOIN amounts
)
SELECT
  user_id, 
  CASE 
    WHEN pos BETWEEN 1 AND 3 THEN 1
    WHEN pos BETWEEN 4 AND 10 THEN 2
    ELSE 3
  END grp,
  SUM(amount_paid) amount_paid
FROM (
  SELECT 
    user_id, amount_paid, 
    ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY amount_paid DESC) pos
  FROM customer 
)
GROUP BY user_id, grp
ORDER BY user_id, grp   

输出如下所示

user_id grp amount_paid  
1       1   147.0    
1       2   323.0    
1       3   879.0    
2       1   147.0    
2       2   323.0    
2       3   879.0    
 . . .    

所以你仍然需要计算份额(根据你的问题并希望)对你来说不是问题

增加了份额计算

#standardSQL
WITH grps AS (
  SELECT
    user_id, 
    CASE 
      WHEN pos BETWEEN 1 AND 3 THEN 1
      WHEN pos BETWEEN 4 AND 10 THEN 2
      ELSE 3
    END grp,
    SUM(amount_paid) amount_paid
  FROM (
    SELECT 
      user_id, amount_paid, 
      ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY amount_paid DESC) pos
    FROM customer 
  )
  GROUP BY user_id, grp
)
SELECT * ,
  ROUND(amount_paid / SUM(amount_paid) OVER(PARTITION BY user_id), 3) share
FROM grps
-- ORDER BY user_id, grp   

【讨论】:

非常感谢米哈伊尔 :) 嵌套查询会很好 - 我认为没有必要一次性完成所有操作。它当然很性感,但更容易出错并且难以维护。对嵌套查询感觉良好 - 只要尝试让我们知道是否仍需要帮助:o) 嗨,米哈伊尔,我试过了,但没有成功。您能指导我如何解决这个问题吗? 您能否更具体地了解您的问题。到底什么不适合你? 感谢米哈伊尔的帮助。我将获得更多关于 SQL 分区的知识,以用于未来的任务。

以上是关于在表上聚合查询?的主要内容,如果未能解决你的问题,请参考以下文章

为啥一个 group by 的聚合这么慢?

查看在表上具有自联接

为每个提取的记录在其他表上计算聚合 - 性能

在左连接表上使用 WHERE OR 时查询很慢?

在 SQL 表上使用 pyspark 编写 where 查询

mysql表上的统计聚合