Как объединить три подзапроса и правильно рассчитать пересечение? - PullRequest
0 голосов
/ 22 ноября 2018

Я хотел бы узнать, сколько у меня лояльных пользователей.Определение таково, что пользователь должен входить в систему как минимум один раз в каждый скользящий месяц.

Если пользователь входил в систему один раз между 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;

Результат: enter image description here

1 Ответ

0 голосов
/ 22 ноября 2018

Поскольку вас волнует только то, что пользователь вошел в систему хотя бы один раз за период времени, нет необходимости выполнять подсчет на пользователя за каждый период времени.Любой пользователь, подключившийся в указанные периоды времени, появится в таблице a, b или c соответственно, и, поскольку вы JOIN объединяете их вместе в поле username, только пользователи, вошедшие в системувсе три периода времени появятся в наборе результатов.Таким образом, простой COUNT(*) в вашем внешнем запросе (вместо a.Count, b.Count , c.Count) даст вам желаемый результат.

Если один и тот же username можно использовать в разных странах, вам потребуетсясгруппируйте по username и country в каждом из подзапросов, а также присоединитесь к username и country.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...