针对类别和子类别的多个分组计数

eni9jsuy  于 2021-07-27  发布在  Java
关注(0)|答案(1)|浏览(460)

我试图从mysql 5.7数据库中查询分析数据,以便在前端显示。这个数据是一个多对多的结构,我想聚合两列,一列基于上一列中的信息,按日期分组和计数。
目的是获取以下格式的数据(参见示例数据):

entry_date | cat_name | subcat_name | subcat_count | total_count
-----------|----------|-------------|--------------|------
2020-07-28 | #TestOne | Alpha       | 1            | 2
2020-07-28 | #TestOne | Delta       | 1            | 2
2020-07-27 | #TestTwo | Bravo       | 1            | 2
2020-07-27 | #TestTwo | Charlie     | 1            | 2
2020-07-26 | #TestOne | Charlie     | 1            | 2
2020-07-26 | #TestOne | Bravo       | 1            | 2
2020-07-25 | #TestTwo | Delta       | 1            | 2
2020-07-25 | #TestTwo | Alpha       | 1            | 2

在上述数据中, value 是在给定日期针对给定场景的给定类型的数量,以及 total 是在给定的一天针对某个场景的所有类型的数量。所以如果有一百篇文章 Alpha 总有一天,这个值 100 总数是 100 . 如果还有上百篇文章 Delta ,总数将变成 200 .
在我意识到自己迷路之前,我已经走了这么远:

SELECT
    ct.entry_id,
    DATE(FROM_UNIXTIME(ct.entry_date)) AS entry_date,
    cg.group_name,
    c.cat_name
FROM
    category_posts cp
    LEFT JOIN channel_titles ct ON ct.entry_id = cp.entry_id
    LEFT JOIN categories c ON c.cat_id = cp.cat_id
    LEFT JOIN category_groups cg ON cg.group_id = c.group_id
WHERE
    cg.group_name = 'Group A'
    OR cg.group_name = 'Group B'
GROUP BY
    entry_date,
    group_name,
    cat_name
ORDER BY
    entry_id,
    FIELD(group_name, 'Group A', 'Group B')

这以一种不可靠的、不太有用的格式返回数据,但是还可以——如果你能绝对确定a组中是否存在记录的话,那我就不可能了。

entry_id | entry_date | group_name | cat_name
---------|------------|------------|---------
1        | 2020-07-28 | Group A    | #TestOne
1        | 2020-07-28 | Group B    | Alpha
1        | 2020-07-28 | Group B    | Delta
2        | 2020-07-27 | Group A    | #TestTwo
2        | 2020-07-27 | Group B    | Bravo
2        | 2020-07-27 | Group B    | Charlie
3        | 2020-07-26 | Group A    | #TestOne
3        | 2020-07-26 | Group B    | Charlie
3        | 2020-07-26 | Group B    | Bravo
4        | 2020-07-25 | Group A    | #TestTwo
4        | 2020-07-25 | Group B    | Delta
4        | 2020-07-25 | Group B    | Alpha

实体关系图

示例数据

类别\u组

group_id | group_name
---------|------------------------------
1        | Group A
2        | Group B

类别

cat_id | group_id | cat_name
-------|----------|-------------------
1      | 1        | #TestOne
2      | 1        | #TestTwo
3      | 2        | Alpha
4      | 2        | Bravo
5      | 2        | Charlie
6      | 2        | Delta

职位类别

cat_id | entry_id
-------|---------
1      | 1
2      | 2
1      | 3
2      | 4
3      | 1
4      | 2
5      | 3
6      | 4
6      | 1
5      | 2
4      | 3
3      | 4

频道标题

entry_id | entry_date
---------|-----------
1        | 1595940540 (07/28/2020)
2        | 1595882160 (07/27/2020)
3        | 1595721600 (07/26/2020)
4        | 1595635200 (07/25/2020)
lzfw57am

lzfw57am1#

问题的原始版本没有指定mysql 5.7。这个答案需要mysql 8.0。
但我认为这只是一个带有窗口函数的聚合查询:

SELECT ct.entry_id,
       DATE(FROM_UNIXTIME(ct.entry_date)) AS entry_date,
       cg.group_name,
       COUNT(*) as value,
       SUM(COUNT(*)) OVER (PARTITION BY entry_id,  DATE(FROM_UNIXTIME(ct.entry_date)) as total
FROM category_posts cp JOIN
     channel_titles ct
     ON ct.entry_id = cp.entry_id JOIN
     categories c
     ON c.cat_id = cp.cat_id JOIN
     category_groups cg
     ON cg.group_id = c.group_id
WHERE cg.group_name IN ( 'Group A', 'Group B' )
GROUP BY entry_date, group_name;

我移除了 LEFT JOIN 因为你的数据似乎都是匹配的,而你的结果却没有 NULL 键列中的值。

相关问题