Группировка запросов MySQL по ip-адресу, идентификатору пользователя и метке времени

#mysql #sql

#mysql #sql

Вопрос:

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

Запрос должен учитывать следующее требование:

  • Несколько строк с одного и того же ip_from в один и тот же день для одного и того же org_id могут учитываться только как 1.

У меня есть таблица в mysql, подобная этой:

  -------- ---------- -------------- ----------------- ----------------- ------------ --------------------- 
| org_id | org_name | user_id_from | auth_level_from |     ip_from     | region_org |      timestamp      |
 -------- ---------- -------------- ----------------- ----------------- ------------ --------------------- 
|      1 | test1    | NULL         | NULL            | 123.456.789.012 | Antwerpen  | 2019-03-06 00:00:00 |
|      2 | test2    | 3            | 1               | 454.454.454.454 | NULL       | 2019-03-06 00:00:00 |
|      1 | test1    | 5            | 2               | 111.111.111.111 | Antwerpen  | 2019-03-05 10:00:00 |
|      1 | test1    | 5            | 2               | 111.111.111.111 | Antwerpen  | 2019-03-05 11:00:00 |
|      1 | test1    | 5            | 2               | 111.111.111.111 | Antwerpen  | 2019-03-05 12:00:00 |
|      1 | test1    | 100          | 1               | 999.999.999.999 | Antwerpen  | 2019-03-05 12:00:00 |
 -------- ---------- -------------- ----------------- ----------------- ------------ --------------------- 
  

Столбец org_id содержит идентификатор организации, org_name содержит название.

Столбец User_id_from содержит user_id пользователя, который вошел в систему и просматривает страницу профиля (анонимный пользователь также может просмотреть это, поэтому оно может быть нулевым). Auth_level_from заполняется, если пользователь входил в систему, в противном случае значение равно НУЛЮ.

ip_from содержит IP-адрес пользователя, вошедшего в систему через $_SERVER[‘remote_addr’] (я знаю, что это можно изменить, но для моего варианта использования это не имеет значения).

Region_org содержит регион, в котором находится организация, обратите внимание, что организация может находиться в нескольких регионах, в этом случае я вставлю 2-ю строку, точно такую же, как предыдущая, но только с другим region_org. Но оно также может быть нулевым

Наконец, временная метка отслеживает, когда было вставлено событие.

Вот как выглядит мой запрос:

 SELECT org_id, org_name, count(*) as total, DATE(timestamp) as date
FROM `org_profile_views_events`
WHERE region_org = 'antwerpen'
GROUP BY org_id, ip_from, DATE(timestamp)
  

Но он возвращает общую сумму для всех строк, в этом примере он возвращает

 org_id = 1
org_name = test1
total = 4
date = 2019-03-05

org_id = 1
org_name = test1
total = 1
date = 2019-03-06

org_id = 2
org_name = test2
total = 1
date = 2019-03-06
  

Хотя я бы хотел, чтобы он возвращал

 org_id = 1
org_name = test1
total = 2
date = 2019-03-05

org_id = 1
org_name = test1
total = 1
date = 2019-03-06

org_id = 2
org_name = test2
total = 1
date = 2019-03-06
  

(поскольку в 2019-03-05 было 3 события с одного IP-адреса и 1 с другого IP-адреса)

Ответ №1:

Я думаю, вы ищете count(DISTINCT ip_from)

 SELECT org_id, org_name, count(distinct ip_from) as total, DATE(timestamp) as date
FROM `org_profile_views_events`
WHERE region_org = 'antwerpen'
GROUP BY org_id, org_name, DATE(timestamp)