sql - 如何加入三个子查询并正确计算交叉点?
问题描述
我想知道我有多少忠实用户。其定义是用户需要每个滚动月至少登录一次。
如果用户在 2018-08-21 和 2018-09-21 之间登录一次,在 2018-09-21 和 2018-10-21 之间登录一次,在 2018-10-21 和 2018-11-21 之间登录一次,那么这是一个忠实的用户。
我认为实现这一目标的最佳方法是加入这三个时间定义的子查询。但我不知道如何计算它?每个子查询显示不同的计数。我是否必须将最低值视为交叉点?还是我做错了?
select p.country, round(SUM(a.GBytes+b.GBytes+c.GBytes), 2) as `Traffic`, a.Count, b.Count , c.Count
from (
SELECT username,
SUBSTRING_INDEX( callingstationid, '=', 1 ) as IP,
(SUM(`acctinputoctets`)+SUM(`acctoutputoctets`))/1000/1000/1000 as GBytes,
count(username) as Count
FROM radacct
WHERE (`acctstarttime` BETWEEN '2018-08-21 22:13:54.286223' AND '2018-09-21 22:13:54.286223')
GROUP BY username
) a join (
SELECT username,
SUBSTRING_INDEX( callingstationid, '=', 1 ) as IP,
(SUM(`acctinputoctets`)+SUM(`acctoutputoctets`))/1000/1000/1000 as GBytes,
count(username) as Count
FROM radacct
WHERE (`acctstarttime` BETWEEN '2018-09-21 22:13:54.286223' AND '2018-10-21 22:13:54.286223')
GROUP BY username
) b on a.username = b.username
join (
SELECT username,
SUBSTRING_INDEX( callingstationid, '=', 1 ) as IP,
(SUM(`acctinputoctets`)+SUM(`acctoutputoctets`))/1000/1000/1000 as GBytes,
count(username) as Count
FROM radacct
WHERE (`acctstarttime` BETWEEN '2018-10-21 22:13:54.286223' AND '2018-11-21 22:13:54.286223')
GROUP BY username
) c on b.username = c.username
join cache_db.global_ip p on p.ip = a.IP
join cache_db.global_ip p2 on p2.ip = b.IP
join cache_db.global_ip p3 on p3.ip = c.IP
group by country;
解决方案
由于您只关心用户是否在每个时间段内至少登录过一次,因此无需对每个用户在每个时间段执行计数。在给定时间段内连接的任何用户都将出现在表中a
,b
或者c
分别出现在字段中,并且由于您将JOIN
他们一起放在username
字段中,因此只有在所有三个时间段内都登录过的用户才会出现在结果集中。因此COUNT(*)
,您的外部查询中的简单(代替a.Count, b.Count , c.Count
)将为您提供所需的结果。
如果username
可以在不同的国家/地区使用相同的方法,那么您将需要在每个子查询中按username
和分组,country
并加入username
和country
。
推荐阅读
- java - 如果语句在程序中无法正常工作以确定三角形类型
- node.js - 我试图抓取的网站阻止了我,因为我正在使用自动化工具,我该如何解决这个问题?
- reactjs - 如何在反应管理数据网格中环回远程 api 响应负载
- javascript - 对某些网站的 Node js 请求返回带有问号的菱形
- javascript - 发送 JSON 格式的对象并将其转换回来
- javascript - 循环成功后,整个页面被文本“XSS”替换
- python - 为什么当 X 小于 0.5 时 sqrt(1-4*pow(X,2)) 显示数学域错误?
- file - “通道”类型的字段给出错误“无法默认初始化具有泛型类型的变量”
- java - 在 Java 和 golang 中使用 AES 时获得不同的结果(密文)
- jmeter - 将 Web 服务响应写入 Excel