简体   繁体   English

GROUP_CONCAT中的MySQL COUNT

[英]MySQL COUNT within GROUP_CONCAT

I have created MySQL table like this. 我已经创建了这样的MySQL表。

CREATE TABLE `log_info` (
 `log_id` int(11) NOT NULL AUTO_INCREMENT,
 `log_datetime` datetime NOT NULL,
 `log_attacker_ip` int(11) NOT NULL,
 `log_event` varchar(250) NOT NULL,
 `log_service_port` varchar(10) NOT NULL,
 `log_target_ip` int(11) NOT NULL,
 `log_severity` varchar(3) NOT NULL,
 PRIMARY KEY (`log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=113 DEFAULT CHARSET=latin1

With a values of this: 使用以下值:

INSERT INTO `log_info` (`log_id`, `log_datetime`, `log_attacker_ip`, `log_event`, `log_service_port`, `log_target_ip`, `log_severity`) VALUES
(1, '2018-11-13 00:16:45', 16843009, 'Traffic forward message', '80', 0, '5'),
(2, '2018-11-13 00:17:21', 16843009, 'Traffic forward message', '80', 0, '5'),
(3, '2018-11-13 00:17:24', 16843009, 'Traffic forward message', '80', 0, '5'),
(4, '2018-11-13 00:17:27', 16843009, 'Traffic forward message', '80', 0, '5'),
(5, '2018-11-13 00:17:30', 16843009, 'Traffic forward message', '80', 0, '5'),
(6, '2018-11-13 00:17:32', 16843009, 'Traffic forward message', '80', 0, '2'),
(7, '2018-11-13 00:17:34', 16843009, 'Traffic forward message', '80', 0, '5'),
(8, '2018-11-13 00:17:36', 16843009, 'Traffic forward message', '80', 0, '5'),
(9, '2018-11-13 00:17:39', 16843009, 'Traffic forward message', '80', 0, '1'),
(10, '2018-11-13 00:17:41', 16843009, 'Traffic forward message', '80', 0, '5'),
(11, '2018-11-13 00:17:44', 16843009, 'Traffic forward message', '80', 0, '1'),
(12, '2018-11-13 00:17:46', 16843009, 'Traffic forward message', '80', 0, '5'),
(13, '2018-11-13 00:17:48', 16843009, 'Traffic forward message', '80', 0, '4'),
(14, '2018-11-13 00:17:50', 16843009, 'Traffic forward message', '80', 0, '5'),
(15, '2018-11-13 00:17:53', 16843009, 'Traffic forward message', '80', 0, '5'),
(16, '2018-11-13 00:17:55', 16843009, 'Traffic forward message', '80', 0, '5'),
(17, '2018-11-13 00:17:57', 16843009, 'Traffic forward message', '80', 0, '5'),
(18, '2018-11-13 00:17:59', 16843009, 'ICMP', '80', 0, '3'),
(19, '2018-11-13 01:55:07', 16843009, 'ICMP', '80', 0, '5'),
(101, '2018-11-13 22:11:15', 134744072, 'bla', '443', 134744072, '4'),
(102, '2018-11-13 22:48:12', 134744072, 'bla', '443', 134744072, '4'),
(103, '2018-11-13 22:48:15', 134744072, 'bla', '443', 134744072, '4'),
(104, '2018-11-13 22:50:52', 2071690107, 'grrr', '21', 167837997, '2'),
(105, '2018-11-13 22:50:55', 2071690107, 'grrr', '21', 167837997, '2'),
(106, '2018-11-13 22:50:57', 2071690107, 'grrr', '21', 167837997, '2'),
(107, '2018-11-13 22:51:00', 2071690107, 'grrr', '21', 167837997, '2'),
(108, '2018-11-13 22:51:02', 2071690107, 'grrr', '21', 167837997, '2'),
(109, '2018-11-13 22:51:15', 2071690107, 'grrr', '21', 167903493, '2'),
(110, '2018-11-13 22:52:35', 2071690107, 'shhh', '0', 168433945, '1'),
(111, '2018-11-13 22:52:39', 2071690107, 'shhh', '0', 168433945, '1'),
(112, '2018-11-13 23:04:59', 134744072, 'bla', '443', 134744072, '4');

I having a little trouble to split COUNT(portno) for column [occurences] by using GROUP_CONCAT. 我通过使用GROUP_CONCAT为列[出现]拆分COUNT(portno)有点麻烦。

My Query: 我的查询:

SELECT MAX(log_id) AS 'log_id', MAX(log_datetime) AS 'recent_datetime', INET_NTOA(log_attacker_ip) AS 'attacker_IP', GROUP_CONCAT(DISTINCT log_service_port SEPARATOR ', ') AS 'portno', COUNT(*) AS 'occurences'
FROM log_info
WHERE log_datetime > NOW() - INTERVAL 30 DAY
AND log_datetime <= NOW()
GROUP BY attacker_IP
ORDER BY recent_datetime DESC

Here is my result: 这是我的结果:

+--------+---------------------+-----------------+--------+------------+
| log_id | recent_datetime     | attacker_IP     | portno | occurences |
+--------+---------------------+-----------------+--------+------------+
|    112 | 2018-11-13 23:04:59 | 8.8.8.8         | 443    |          4 |
|    111 | 2018-11-13 22:52:39 | 123.123.123.123 | 0, 21  |          8 |
|     19 | 2018-11-13 01:55:07 | 1.1.1.1         | 80     |         19 |
+--------+---------------------+-----------------+--------+------------+

I need to use GROUP_CONCAT on the column [occurences] so that it separate just like column [portno]. 我需要在[occurences]列上使用GROUP_CONCAT,以便它像列[portno]一样分开。

I'm presuming you want to have a list of occurrences that maps to the list of ports eg if port list is 0, 21 you want 2, 6 which is the count of occurrences for each of those ports. 我假设你想要一个映射到端口列表的事件列表,例如,如果端口列表是0, 21你想要2, 6 ,这是每个端口的出现次数。 In that case, you can use this query. 在这种情况下,您可以使用此查询。 You need to use two levels of grouping, first by attacker_IP and portno and then by attacker_IP to get this data: 您需要使用两个级别的分组,首先是attacker_IPportno ,然后是attacker_IP来获取此数据:

SELECT MAX(log_id) AS log_id
     , MAX(recent_datetime) AS recent_datetime
     , attacker_IP
     , GROUP_CONCAT(portno) AS ports
     , GROUP_CONCAT(occurrences) AS occurrences
FROM (
    SELECT MAX(log_id) AS log_id
         , MAX(log_datetime) AS recent_datetime
         , INET_NTOA(log_attacker_ip) AS attacker_IP
         , log_service_port AS portno
         , COUNT(*) AS occurrences
    FROM log_info
    WHERE log_datetime > NOW() - INTERVAL 30 DAY
    AND log_datetime <= NOW()
    GROUP BY attacker_IP, portno) AS d
GROUP BY attacker_IP
ORDER BY recent_datetime DESC

Output: 输出:

log_id  recent_datetime         attacker_IP         ports   occurrences
112     2018-11-13 23:04:59     8.8.8.8             443     4
111     2018-11-13 22:52:39     123.123.123.123     21,0    6,2
19      2018-11-13 01:55:07     1.1.1.1             80      19

Demo on dbfiddle 在dbfiddle上演示

I suggest to first use the next query: 我建议先使用下一个查询:

SELECT
    MAX(log_id) AS 'log_id',
    MAX(log_datetime) AS 'recent_datetime',
    INET_NTOA(log_attacker_ip) AS 'attacker_IP',
    log_service_port AS 'portno',
    COUNT(*) AS 'occurences'
FROM
    log_info
WHERE
    log_datetime > NOW() - INTERVAL 30 DAY
AND
    log_datetime <= NOW()
GROUP BY
    attacker_IP, portno
ORDER BY
    recent_datetime DESC

The previous query will displays reports for the differentes tuples of (attacker_IP, portno) . 上一个查询将显示(attacker_IP, portno)的不同元组的报告。 Now, if you still want to concatenate ports numbers and occurences, you can query the previous one, like this: 现在,如果您仍想连接端口号和出现,可以查询前一个,如下所示:

SELECT
    MAX(ip_port_logs.log_id) AS 'log_id',
    MAX(ip_port_logs.recent_datetime) AS 'recent_datetime',
    ip_port_logs.attacker_IP,
    GROUP_CONCAT(ip_port_logs.portno SEPARATOR ', ') AS 'ports',
    GROUP_CONCAT(ip_port_logs.occurences SEPARATOR ', ') AS 'ports_occurences'
FROM
    ( SELECT
          MAX(log_id) AS 'log_id',
          MAX(log_datetime) AS 'recent_datetime',
          INET_NTOA(log_attacker_ip) AS 'attacker_IP',
          log_service_port AS 'portno',
          COUNT(*) AS 'occurences'
      FROM
          log_info
      WHERE
          log_datetime > NOW() - INTERVAL 30 DAY
      AND
          log_datetime <= NOW()
      GROUP BY
          attacker_IP, portno
      ORDER BY
          recent_datetime DESC ) AS ip_port_logs
GROUP BY
    ip_port_logs.attacker_IP

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM