1

有一张活动表

created_at DATETIME
event_type STRING 
# Some other columns with data about the event

我想做的是能够获得每天每event_type.

因此,我将事件分组以获取每个事件每天的计数:

# Lazily used date_bucket in GROUP BY since it's valid MySQL.
# Is that bad since it's not standard SQL?
#
SELECT 
    DATE(created_at) as date_bucket, 
    event_type, 
    COUNT(*) as number
FROM 
    example_table 
GROUP BY
    date_bucket, event_type

如果我们有行

# Columns (date_bucket, event_type, number)
#
('2020-06-02', 'exampleG1', 5)
('2020-06-02', 'exampleG2', 10)
('2020-06-02', 'exampleG3', 20)
('2020-06-03', 'exampleG1', 10)

我希望能够得到与处理相同的东西

# Columns (date_bucket, exampleG1, exampleG2, exampleG3)
#
('2020-06-02', 15/35, 10/35, 20/35)
('2020-06-03', 10/10, 0, 0)

我事先不知道不同的event_type值,并且并非所有组值都可能在所有日子都存在,在这种情况下,该类型的值在那天应该是 0。

我正在考虑进行某种枢轴操作,但似乎 MySQL 不支持枢轴,所以我有点不知所措。

如果我提前知道有效事件类型的集合,我想我可以对可能的类型进行一些讨厌的详细查询,但集合是可变的。

有没有一种优雅的方式来实现这一目标?

4

1 回答 1

1

我事先不知道不同的 event_type 值

您要求动态 SQL。也就是说,从另一个列出不同event_type值的查询动态构建查询字符串,然后执行它。在 MySQL 中,这是使用准备好的语句实现的。

这是如何做到的:

select @sql := group_concat(distinct
    'sum(case when event_type = ''', 
    event_type, ''' then number else 0 end)/sum(number) as `ratio_', 
    event_type, '`'
) 
from example_table;

set @sql = concat(
    'select date(created_at) date_bucket, ', 
    @sql, 
    ' from example_table group by date(created_at) order by date_bucket'
);

-- debug
select @sql;

-- execute
prepare stmt from @sql;
execute stmt;
deallocate prepare stmt; 

对于您的示例数据,这会产生以下查询:

select 
    date(created_at) date_bucket, 
    sum(case when event_type = 'exampleG1' then number else 0 end)/sum(number) as `ratio_exampleG1`,
    sum(case when event_type = 'exampleG2' then number else 0 end)/sum(number) as `ratio_exampleG2`,
    sum(case when event_type = 'exampleG3' then number else 0 end)/sum(number) as `ratio_exampleG3` 
from example_table 
group by date(created_at) 
order by date_bucket

结果如下:

日期桶 | ratio_exampleG1 | ratio_exampleG2 | ratio_exampleG3
:------------ | --------------: | --------------: | --------------:
2020-06-02 | 0.1429 | 0.2857 | 0.5714
2020-06-03 | 1.0000 | 0.0000 | 0.0000

DB Fiddle 上的演示

于 2020-06-03T12:15:48.333 回答