Получить количество записей с определенным значением, но только один раз для уникального поля - PullRequest
0 голосов
/ 25 сентября 2018

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

У меня подключена серия датчиков (30+)в мою сеть.Через разные промежутки времени я запрашиваю их состояние, и каждое из устройств отвечает с n-количеством логических значений, где n может быть любым от нуля до 120 (таким образом, ответ может быть пустым объектом, списком из 120 логических значений или любым количеством между).

Для каждого полученного логического значения я создаю новую запись вместе с MAC-адресом устройства и отметкой времени.Например ( см. Также этот sqlfiddle ):

+----+-------------------+---------------------+--------+    
| id | device_address    | timestamp           | status |
+----+-------------------+---------------------+--------+    
|  1 | f2:49:d2:17:5d:8d | 2018-09-22 15:54:51 |      0 |
|  2 | fd:30:ec:08:67:9a | 2018-09-22 15:54:56 |      0 |
|  3 | f8:8d:d9:64:a4:7c | 2018-09-22 15:54:58 |      1 |
|  4 | f2:49:d2:17:5d:8d | 2018-09-22 15:55:51 |      0 |
|  5 | f2:49:d2:17:5d:8d | 2018-09-22 15:55:52 |      0 |
|  6 | fd:30:ec:08:67:9a | 2018-09-22 15:55:56 |      1 |
|  7 | f8:8d:d9:64:a4:7c | 2018-09-22 15:55:58 |      1 |
|  8 | f2:49:d2:17:5d:8d | 2018-09-22 15:56:52 |      0 |
|  9 | f2:49:d2:17:5d:8d | 2018-09-22 15:57:52 |      1 |
| 10 | f2:49:d2:17:5d:8d | 2018-09-22 15:58:52 |      1 |
+----+-------------------+---------------------+--------+

Или с заменой MAC-адреса для лучшей читаемости:

+----+-------------------+---------------------+--------+    
| id | device_address    | timestamp           | status |
+----+-------------------+---------------------+--------+    
|  1 | A                 | 2018-09-22 15:54:51 |      0 |
|  2 | BB                | 2018-09-22 15:54:56 |      0 |
|  3 | CCC               | 2018-09-22 15:54:58 |      1 |
|  4 | A                 | 2018-09-22 15:55:51 |      0 |
|  5 | A                 | 2018-09-22 15:55:52 |      0 |
|  6 | BB                | 2018-09-22 15:55:56 |      1 |
|  7 | CCC               | 2018-09-22 15:55:58 |      1 |
|  8 | A                 | 2018-09-22 15:56:52 |      0 |
|  9 | A                 | 2018-09-22 15:57:52 |      1 |
| 10 | A                 | 2018-09-22 15:58:52 |      1 |
+----+-------------------+---------------------+--------+

В конце я хочууметь составлять график этих значений, сгруппированных по интервалам.Например, когда я отображаю данные за последние 2 часа, я хочу использовать 5-минутные интервалы.За интервал я хочу знать, сколько (уникальных) устройств имели статус 1, по крайней мере, один раз за этот период, и сколько было только нолей.Устройства, которые вообще не появляются во временном блоке (потому что они не возвращают логическое значение), не имеют отношения к этому временному блоку

Приведенные выше записи попадают в два таких 5-минутных временных блока:

  • 15: 50: 00 до 15:54:59 - идентификаторы 1 2 3
  • 15: 55: 00 до 15:59:59 - идентификаторы 4 5 6 7 8 9 10

Ответ, который я хотел бы получить, выглядит примерно так:

+---------------------+---------------------------------+-------------------------+    
| timeblock start     | dev w/ at least one status of 1 | dev w/ only status of 0 |
+---------------------+---------------------------------+-------------------------+    
| 2018-09-22 15:50:00 |                               1 |                       2 |
| 2018-09-22 15:55:00 |                               2 |                       1 |
+---------------------+---------------------------------+-------------------------+    

Окончательный результат не обязательно должен быть именно таким, другие результаты, которые могут помочь мне вывести эти числа,тоже работа.То же самое верно для поля метки времени;этот формат 2018-09-22 15:50:00 был бы отличным, но другие форматы также могут позволить мне вычесть то, что было временным блоком.

Делая что-то подобное, я получаю разные временные блоки и количество уникальных устройств в каждом временном блоке, но это считаетсяобщее количество 1 и 0 вместо объединения результатов каждого уникального устройства.

SELECT timestamp, 
SUM(status) as ones, COUNT(status)-SUM(status) as zeroes, 
COUNT(DISTINCT(device_address)) as unique_devices 
FROM records 
GROUP BY UNIX_TIMESTAMP(timestamp) DIV 300 
ORDER BY timestamp ASC

result:

+----------------------+------+--------+----------------+
| timestamp            | ones | zeroes | unique devices |
+----------------------+------+--------+----------------+
| 2018-09-22T15:54:51Z |    1 |      2 |              3 |
| 2018-09-22T15:57:52Z |    4 |      3 |              3 |
+----------------------+------+--------+----------------+

1 Ответ

0 голосов
/ 25 сентября 2018

Использовать условное агрегирование

SELECT timestamp, 
       count(distinct case when status = 1 then device_address end) as ones, 
       count(distinct case when status = 0 then device_address end) as zeros, 
FROM records 
GROUP BY UNIX_TIMESTAMP(timestamp) DIV 300 
ORDER BY timestamp ASC

sqlfiddle demo

...