MySQL 条件文本聚合

标签 mysql database-design aggregate

我目前有以下输入模型:

+---------+-----------+---------+---------+--------+
| user_id |   date    | program |  type   |  more  |
+---------+-----------+---------+---------+--------+
|       1 | 23-Mar-15 | AAA     | init    |        |
|       1 | 21-May-15 | AAA     | 1/3     |        |
|       1 | 22-Sep-15 | AAA     | 1/3     |        |
|       1 | 20-Mar-16 | AAA     | 1/3     |        |
|       1 | 12-Aug-16 | CCC     | init    |        |
|       1 | 27-Jun-18 | CCC     | init    | refund |
|       2 | 16-May-16 | BBB     | init    |        |
|       2 | 12-Aug-16 | BBB     | full    |        |
|       2 | 15-Mar-17 | AAA     | 1/3     |        |
|       2 | 21-Jun-17 | AAA     | 1/3     | refund |
|       3 | 24-May-18 | BBB     | init    |        |
|       3 | 27-May-18 | BBB     | 1/3     |        |
|       3 | 27-Jun-18 | BBB     | 2/3     |        |
|       4 | 27-Jun-18 | AAA     | init    |        |
|       5 | 27-Jun-18 | AAA     | 1/3     |        |
|       5 | 27-Jun-18 | AAA     | 1/3     |        |
+---------+-----------+---------+---------+--------+

我寻找的结果是:

+---------+----------+------------+
| user_id | programs | aggregated |
+---------+----------+------------+
|       1 | AAA      | full       |
|       1 | CCC      | refund     |
|       2 | BBB      | full       |
|       2 | AAA      | refund     |
|       3 | BBB      | 2/3        |
|       4 | AAA      | init       |
|       5 | AAA      | 2/3        |
+---------+----------+------------+

我正在寻求有关如何设计输入表以获得请求结果的建议。在之前的迭代中,我为每个程序提供了数十种不同的选项,但我发现这种方法完全无用。所以我大大简化了可能的程序类型。但我仍然不知道如何使用此输入来聚合数据。如果我太愚蠢,看不到已经可以从现有输入中获得我正在寻找的结果,请为我指明方向。

问题 TL:DR - 我正在寻找使用 MySQL 中当前输入表进行聚合的可能/可行吗? - 如果没有,您建议对我的输入表进行什么样的修改? - 如果是,请指出我正确的方向。

编辑

尝试更详细地描述逻辑:

每个用户可以有多个程序

用户可以获取每个程序的部分,这些部分在类型列中表示。

程序 AAA 在该行中仅具有以下输入选项 init、1/2、1/3 或全部可能(我对此没有影响)。

其他程序有:1/2、2/2、1/3、2/3、3/3、full、init

每个程序都可以将以下状态类型之一作为结果:init、1/2、 1/3、2/3、全额、退款

伪代码:

For every program that user has:
 If there is only one type for a program then result = that type.   
 If there is more than one type of program: 
   check if there are any refund    
    if every program type has refund, then result = refund  
    if there are program type without refund, result = aggregated   
    if there are no refunds, then result = aggregated

最佳答案

SELECT user_id, program,
    CASE 
        WHEN COUNT(DISTINCT type) = 1 THEN MAX(type) -- one type, use that type
        WHEN SUM(more = 'refund') = COUNT(DISTINCT type) THEN 'refund'
        WHEN SUM(IF(LOCATE('/', type), SUBSTRING_INDEX(type, '/', 1), 0)) >= 3 THEN 'full'
        WHEN MAX(LOCATE('/', type)) > 0 THEN CONCAT(SUM(IF(LOCATE('/', type), SUBSTRING_INDEX(type, '/', 1), 0)), '/3')
        ELSE MAX(type)
    AS aggregated
FROM yourTable
GROUP BY user_id, program

DEMO

关于MySQL 条件文本聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50630490/

相关文章:

database - 同一张表上的多对多关系在 UML 中看起来像什么

php - MySQL如何处理大表? (游戏的数据库设计)

mysql的created_at和updated at之间的时间差

MYSQL连接2个表

javascript - 未处理的拒绝 SequelizeEagerLoadingError : film is not associated to film

php - 如何在 MySQL 语句/查询中使 CASE 语句动态化

database-design - 协助使用数据库架构(独立于平台)

python - pandas groupby,然后按列的值选择一行(例如,最小值、最大值)

python - 对 Pandas 数据帧进行计数、平均和连接

elasticsearch - 如何获取包含多个字段的 Elasticsearch 聚合