按同一列分组,但以两种不同的方式聚合

Posted

技术标签:

【中文标题】按同一列分组,但以两种不同的方式聚合【英文标题】:Grouping by same column but aggregating in two different ways 【发布时间】:2019-12-10 18:02:42 【问题描述】:

我有一张带有 schema 的表。我想要一个输出表,其中包含每个帐户的所有交易(T)的计数,以及在某个日期(比如今天 30 天)之后完成的那些交易(每个帐户)的计数。 分组列很常见,即Account,但计数策略不同。使用两个不同的查询并连接结果很容易做到这一点,但是是否可以在单个 sql 查询中做到这一点?

输入:

  Account |  T_id |  T_date 
 ---------|-------|--------- 
  A1      |  t1   |     205 
  A1      |  t2   |     420 
  A1      |  t3   |     180 
  A1      |  t5   |     290 
  A2      |  t6   |     100 

预期输出 (c=200):

  Account |  T_count |  T_count_greater_than_c 
 ---------|----------|------------------------- 
  A1      |        3 |                       2 
  A2      |        2 |                       1 

要实现计数,我们可以这样做

SELECT Account, COUNT(T_id) 
FROM T 
GROUP BY Account

要实现count>c,我们可以这样做

SELECT Account, COUNT(T_id) 
FROM T 
GROUP BY Account 
HAVING T_date > c

如何将两者结合在一个查询中并防止连接操作?

【问题讨论】:

以表格格式提供您的样本数据和预期输出 Its pretty easy to do this using two different queries and join the results 编写您的 2 个查询,通过这些查询您可以获得您的答案,以及示例输入和输出。 第二个查询无效。聚合后没有T_date。必须是SELECT Account, COUNT(*) FROM T WHERE T_date > c GROUP BY Account 顺便说一句:您应该始终使用您正在使用的 DBMS 标记 SQL 问题。你问这个是为了 mysql 吗? SQL 服务器?甲骨文? ... 如何使用该样本数据获得 A2 的 2 计数?为什么你谈论某个日期范围内的交易计数,但在你的样本中做一些完全不同的事情? 【参考方案1】:

在 sum() 中使用 case 或 IF 语句应用条件聚合:

with mydata as(--Replace this with your table
select stack(6,
             1, '2019-08-01', 100,
             1, '2019-08-01', 100,
             1, '2019-07-01', 200,
             2, '2019-08-01', 100,
             2, '2019-08-01', 100,
             2, '2019-07-01', 200
             ) as (account, transaction_date, amount)
)
select account, sum(amount) amount, 
       sum(case when transaction_date < date_sub(current_date,30) then amount else 0 end) amount_beyond_30
  from mydata
 group by account;

结果:

account   amount  amount_beyond_30
    1       400     200
    2       400     200
    Time taken: 40.716 seconds, Fetched: 2 row(s)

抱歉,我的示例是针对 Hive SQL 的,您的数据库中的某些函数可能会有所不同,但希望您现在了解如何在 SQL 中进行条件聚合。

添加示例和 SQ 后更新L:

SELECT Account, COUNT(T_id) as cnt,
       count(case when T_date > 200 then 1 else null end) as T_count_greater_than_c
  FROM T 
 GROUP BY Account

【讨论】:

以上是关于按同一列分组,但以两种不同的方式聚合的主要内容,如果未能解决你的问题,请参考以下文章

如何对多个列上的数据集进行分组并同时进行不同的聚合? Python

Pandas实现groupby分组聚合后不同列数据统计

Mongoose 聚合内部查找按字段分组

为啥以两种不同方式应用随机森林分类器的特征选择结果不同

pyspark 聚合的不同列的不同操作

通过对不同列使用不同聚合的 pandas 数据框进行分组