如何每天使用 GROUP BY 制作可以出现在两个不同表格中的 COUNT 个项目?

Posted

技术标签:

【中文标题】如何每天使用 GROUP BY 制作可以出现在两个不同表格中的 COUNT 个项目?【英文标题】:How to make a COUNT of items that can appear in two different tables with a GROUP BY per day? 【发布时间】:2021-10-12 23:09:40 【问题描述】:

我有一个 SQL 查询,它告诉我有多少人在过去一天至少登录过一次,我想查询一下过去有多少人至少登录过一次或阅读过电子邮件每种语言的年份 (Lang)。

以这个架构为例:

CREATE TABLE sessions
    (`App Type` varchar(11), `Lang` varchar(2), `Session ID` int, `session_time` datetime, `User ID` int)
;
    
INSERT INTO sessions
    (`App Type`, `Lang`, `Session ID`, `session_time`, `User ID`)
VALUES
    #july 2021
    ('browser', 'fr', 46960339, '2021-07-29 00:00:00', 1292997),
    ('browser', 'es', 46960407, '2021-07-29 00:00:00', 1055040),
    ('pwa_android', 'fr', 46960412, '2021-07-29 00:00:00', 1120109),
    ('browser', 'fr', 46960391, '2021-07-29 00:00:00', 955480),
    ('pwa_android', 'en', 46960389, '2021-07-29 00:00:00', 800169),
    ('browser', 'es', 46960353, '2021-07-29 00:00:00', 1193745),
    # june 2021
    ('browser', 'fr', 46960339, '2021-06-29 00:00:00', 1292997),
    ('browser', 'es', 46960407, '2021-06-29 00:00:00', 1055040),
    ('pwa_android', 'fr', 46960412, '2021-06-29 00:00:00', 1120109),
    ('browser', 'fr', 46960391, '2021-06-29 00:00:00', 955480),
    ('pwa_android', 'en', 46960389, '2021-06-29 00:00:00', 800169),
    ('browser', 'es', 46960353, '2021-06-29 00:00:00', 12345),
    # june 2020
    ('browser', 'fr', 46960339, '2020-06-29 00:00:00', 1292997),
    ('browser', 'es', 46960407, '2020-06-29 00:00:00', 1055040),
    ('pwa_android', 'fr', 46960412, '2020-06-29 00:00:00', 1120109),
    ('browser', 'fr', 46960391, '2020-06-29 00:00:00', 955480),
    ('pwa_android', 'en', 46960389, '2020-06-29 00:00:00', 800169),
    ('browser', 'es', 46960353, '2020-06-29 00:00:00', 54321)

;


CREATE TABLE unique_open_emails
    (`date` datetime, `lang` varchar(2), `user_id` int)
;
    
INSERT INTO unique_open_emails
    (`date`, `lang`, `user_id`)
VALUES
    ('2016-04-12 00:00:00', 'fr', 115434),
    ('2016-04-13 00:00:00', 'fr', 11357),
    ('2016-04-13 00:00:00', 'fr', 137481),
    ('2016-04-13 00:00:00', 'fr', 10296),
    ('2016-04-13 00:00:00', 'fr', 125772),
    ('2016-04-13 00:00:00', 'fr', 955480),
    ('2016-04-13 00:00:00', 'fr', 9269),
    ('2016-04-13 00:00:00', 'fr', 90716),
    ('2016-04-13 00:00:00', 'fr', 26330),
    ('2016-04-13 00:00:00', 'fr', 89072),
    ('2016-04-13 00:00:00', 'fr', 87416),
    ('2016-04-13 00:00:00', 'fr', 88358),
    ('2016-04-13 00:00:00', 'fr', 102515),
    ('2016-04-13 00:00:00', 'fr', 89867),
    ('2016-04-13 00:00:00', 'fr', 119146),
    ('2016-04-13 00:00:00', 'fr', 133316),
    ('2016-04-13 00:00:00', 'fr', 90095),
    ('2016-04-13 00:00:00', 'fr', 16510),
    ('2016-04-13 00:00:00', 'fr', 21530),
    ('2016-04-13 00:00:00', 'fr', 81581),
    ('2016-04-13 00:00:00', 'es', 54321),
    ('2016-04-13 00:00:00', 'fr', 29363),
    ('2016-04-13 00:00:00', 'fr', 90326),
    ('2016-04-13 00:00:00', 'fr', 23961),
    ('2016-04-13 00:00:00', 'fr', 89000),
    ('2016-04-13 00:00:00', 'fr', 9484),
    ('2016-04-13 00:00:00', 'fr', 11845),
    ('2016-04-13 00:00:00', 'fr', 41231),
    ('2016-04-13 00:00:00', 'fr', 588),
    ('2016-04-13 00:00:00', 'fr', 16678),
    ('2016-04-13 00:00:00', 'fr', 19674),
    ('2016-04-13 00:00:00', 'fr', 130113),
    ('2016-04-13 00:00:00', 'fr', 84719),
    ('2016-04-13 00:00:00', 'fr', 123252),
    ('2016-04-13 00:00:00', 'fr', 4676),
    ('2016-04-13 00:00:00', 'fr', 113636),
    ('2016-04-13 00:00:00', 'fr', 17452),
    ('2016-04-13 00:00:00', 'fr', 136544),
    ('2016-04-13 00:00:00', 'fr', 15917),
    ('2016-04-13 00:00:00', 'fr', 82787),
    ('2016-04-13 00:00:00', 'fr', 81620),
    ('2016-04-13 00:00:00', 'fr', 135298),
    ('2016-04-13 00:00:00', 'fr', 15643),
    ('2016-04-13 00:00:00', 'fr', 80981),
    ('2016-04-13 00:00:00', 'fr', 51827),
    ('2016-04-13 00:00:00', 'fr', 90554),
    ('2016-04-13 00:00:00', 'fr', 10277),
    ('2016-04-13 00:00:00', 'fr', 24432),
    ('2016-04-13 00:00:00', 'fr', 6651),
    ('2016-04-13 00:00:00', 'fr', 64106),
    ('2016-04-13 00:00:00', 'fr', 119080),
    ('2016-04-13 00:00:00', 'fr', 72659),
    ('2016-04-13 00:00:00', 'fr', 130004),
    ('2016-04-13 00:00:00', 'fr', 22320),
    ('2016-04-13 00:00:00', 'fr', 136966),
    ('2016-04-13 00:00:00', 'fr', 11317),
    ('2016-04-13 00:00:00', 'fr', 79031),
    ('2016-04-13 00:00:00', 'fr', 90800),
    ('2016-04-13 00:00:00', 'fr', 16149),
    ('2016-04-13 00:00:00', 'fr', 61463),
    ('2016-04-13 00:00:00', 'fr', 5383),
    ('2016-04-13 00:00:00', 'fr', 87674),
    ('2016-04-13 00:00:00', 'fr', 10223),
    ('2016-04-13 00:00:00', 'fr', 88100),
    ('2016-04-13 00:00:00', 'fr', 91691),
    ('2016-04-13 00:00:00', 'fr', 89423),
    ('2016-04-13 00:00:00', 'fr', 126),
    ('2016-04-13 00:00:00', 'fr', 86858),
    ('2016-04-13 00:00:00', 'fr', 1419),
    ('2016-04-13 00:00:00', 'fr', 89849),
    ('2016-04-13 00:00:00', 'fr', 15721),
    ('2016-04-13 00:00:00', 'fr', 86444),
    ('2016-04-13 00:00:00', 'fr', 130822),
    ('2016-04-13 00:00:00', 'fr', 73991),
    ('2016-04-13 00:00:00', 'fr', 113969),
    ('2016-04-13 00:00:00', 'fr', 16779),
    ('2016-04-13 00:00:00', 'fr', 71267),
    ('2016-04-13 00:00:00', 'fr', 61067),
    ('2016-04-13 00:00:00', 'fr', 89081),
    ('2016-04-13 00:00:00', 'fr', 24815),
    ('2016-04-13 00:00:00', 'fr', 91928),
    ('2016-04-13 00:00:00', 'fr', 13071),
    ('2016-04-13 00:00:00', 'fr', 1942),
    ('2016-04-13 00:00:00', 'fr', 44012),
    ('2016-04-13 00:00:00', 'fr', 52049),
    ('2016-04-13 00:00:00', 'fr', 6626),
    ('2016-04-13 00:00:00', 'fr', 7034),
    ('2016-04-13 00:00:00', 'fr', 20442),
    ('2016-04-13 00:00:00', 'fr', 75422),
    ('2016-04-13 00:00:00', 'fr', 16673),
    ('2016-04-13 00:00:00', 'fr', 17325),
    ('2016-04-13 00:00:00', 'fr', 7898),
    ('2016-04-13 00:00:00', 'fr', 85226),
    ('2016-04-13 00:00:00', 'fr', 136557),
    ('2016-04-13 00:00:00', 'fr', 134423),
    ('2016-04-13 00:00:00', 'fr', 68723),
    ('2016-04-13 00:00:00', 'en', 118331),
    ('2016-04-13 00:00:00', 'fr', 91298),
    ('2016-04-13 00:00:00', 'fr', 136046),
    ('2016-04-13 00:00:00', 'fr', 136891),
    ('2016-04-13 00:00:00', 'fr', 9169),
    ('2016-04-13 00:00:00', 'fr', 88946),
    ('2016-04-13 00:00:00', 'fr', 115919),
    ('2016-04-13 00:00:00', 'fr', 44492),
    ('2016-04-13 00:00:00', 'fr', 89783),
    ('2016-04-13 00:00:00', 'fr', 137482),
    ('2016-04-13 00:00:00', 'fr', 10072),
    ('2016-04-13 00:00:00', 'fr', 38636),
    ('2016-04-13 00:00:00', 'fr', 11227),
    ('2016-04-13 00:00:00', 'fr', 108310),
    ('2016-04-13 00:00:00', 'fr', 4700),
    ('2016-04-13 00:00:00', 'fr', 17976),
    ('2016-04-13 00:00:00', 'fr', 8580),
    ('2016-04-13 00:00:00', 'fr', 91316)
;

我试过了:

SELECT sessions.session_time, `Lang`, (
  SELECT COUNT(DISTINCT(`USER ID`))
  FROM sessions s2 JOIN unique_open_emails u ON s2.`User ID`=u.user_id
  WHERE (s2.session_time BETWEEN DATE_SUB(sessions.session_time, INTERVAL 1 YEAR) AND sessions.session_time)
  OR (u.date BETWEEN DATE_SUB(u.date, INTERVAL 1 YEAR) AND u.date)
) AS alive_users
FROM sessions
GROUP BY sessions.session_time, sessions.Lang

但它会返回:

session_time            Lang    alive_users
2020-06-29T00:00:00Z    en     0   
2020-06-29T00:00:00Z    es     0
2020-06-29T00:00:00Z    fr     0
2021-06-29T00:00:00Z    en     0
2021-06-29T00:00:00Z    es     0
2021-06-29T00:00:00Z    fr     0
2021-07-29T00:00:00Z    en     0
2021-07-29T00:00:00Z    es     0
2021-07-29T00:00:00Z    fr     0

所以不仅日期丢失了,而且数字也错了。

您可以在this Fiddle 进行测试。

我使用 mysql 5.7

另外,只有 unique_open_emails 表的真实数据是 3700 万行,所以查询永远不会完成。我不知道查询是否没有优化(索引和东西),所以如果脚本会更快。

我想我错过了 2016 年的日期,因为我没有在查询中选择它们,只是从会话表中选择日期。你知道我怎样才能包含 2016 年吗?

【问题讨论】:

您的小提琴无法访问。 但它返回: 为显示的数据提供所需的输出。 PS。提供数据的可读小提琴:dbfiddle.uk/… 请解释您的数据。如果您的问题是按年,为什么要按天举一个例子? 【参考方案1】:

我想查询一下在过去一年中,每种语言 (Lang) 有多少人至少登录过一次或阅读过电子邮件。

我想你想要union allgroup by

select lang, count(distinct user_id)
from ((select user_id, lang
       from sessions
       where session_time > now() - interval 1 year
      ) union all
      (select user_id, lang
       from unique_open_emails
       where date > now() - interval 1 year
      )
     ) u
group by lang;

【讨论】:

非常感谢!你知道我怎么能倒退吗?我的意思是计算并在表格中插入过去一年中有多少人在表格中的所有日子里至少登录过一次或阅读了一封电子邮件?

以上是关于如何每天使用 GROUP BY 制作可以出现在两个不同表格中的 COUNT 个项目?的主要内容,如果未能解决你的问题,请参考以下文章

关于group by 两个或以上条件的分析

关于group by 两个或以上条件的分析

关于group by 两个或以上条件的分析

关于group by 两个或以上条件的分析

group by 多个字段

EntityFramework 多个 Group by 查询