gpt4 book ai didi

mysql - 如何统计mysql中的记录数并添加它们?(使用tally)

转载 作者:行者123 更新时间:2023-11-29 12:23:32 25 4
gpt4 key购买 nike

我有一个大表,有570000条记录,我只选择其中一小部分作为示例。例如,table1是这样的:

+---------------------+---------------+
| StartTime | dIPaddr |
+---------------------+---------------+
| 2014-04-09 09:47:53 | 0.210.208.240 |
| 2014-04-09 09:47:53 | 0.210.208.240 |
| 2014-04-09 09:47:55 | 0.210.208.240 |
| 2014-04-09 08:39:55 | 0.210.243.93 |
| 2014-04-09 08:39:57 | 0.210.243.93 |
| 2014-04-09 08:40:00 | 0.210.243.93 |
| 2014-04-09 13:02:25 | 0.210.25.224 |
| 2014-04-09 13:02:25 | 0.210.25.224 |
| 2014-04-09 13:02:25 | 0.210.25.224 |
| 2014-04-09 13:02:27 | 0.210.25.224 |
+---------------------+---------------+

表1表示对于每个目标IP地址(dIPaddr),它有一些网络流,这些流有开始时间(StartTime)。

对于IP:0.210.208.240,它有3个流,但是这三个流的时间不连续,它有两个流09:47:53,一个流为 09:47:55,但没有 09:47:54

对于IP:0.210.243.93,它有一个08:39:55流,一个08:39:57流,1 个流使用 08:40:00,但 0 个流使用 08:39:56,08:39:58,08:39:59

对于IP:0.210.25.224,它有3个13:02:25流,1个13:02:27流, 0 流为 13:02:26

现在我想计算具有相同 StartTime、相同 dIPaddr 的流数,并将它们相加。这意味着,首先计算具有相同StartTime、相同dIPaddr的流数,得到表2:

+---------------------+---------------+---------------+
| StartTime | dIPaddr | count |
+---------------------+---------------+---------------+
| 2014-04-09 09:47:53 | 0.210.208.240 | 2 |
| 2014-04-09 09:47:54 | 0.210.208.240 | 0 |
| 2014-04-09 09:47:55 | 0.210.208.240 | 1 |
| 2014-04-09 08:39:55 | 0.210.243.93 | 1 |
| 2014-04-09 08:39:56 | 0.210.243.93 | 0 |
| 2014-04-09 08:39:57 | 0.210.243.93 | 1 |
| 2014-04-09 08:39:58 | 0.210.243.93 | 0 |
| 2014-04-09 08:39:59 | 0.210.243.93 | 0 |
| 2014-04-09 08:40:00 | 0.210.243.93 | 1 |
| 2014-04-09 13:02:25 | 0.210.25.224 | 3 |
| 2014-04-09 13:02:26 | 0.210.25.224 | 0 |
| 2014-04-09 13:02:27 | 0.210.25.224 | 1 |
+---------------------+---------------+---------------+

从table2中可以看出,对于dIPaddr:0.210.208.240,它有(3条记录),我们将其命名为table_240:

+---------------------+---------------+---------------+
| StartTime | dIPaddr | count |
+---------------------+---------------+---------------+
| 2014-04-09 09:47:53 | 0.210.208.240 | 2 |
| 2014-04-09 09:47:54 | 0.210.208.240 | 0 |
| 2014-04-09 09:47:55 | 0.210.208.240 | 1 |

对于 dIPaddr 0.210.243.93,它有(6 条记录),我们将其命名为 table_93:

| 2014-04-09 08:39:55 | 0.210.243.93  |       1       |
| 2014-04-09 08:39:56 | 0.210.243.93 | 0 |
| 2014-04-09 08:39:57 | 0.210.243.93 | 1 |
| 2014-04-09 08:39:58 | 0.210.243.93 | 0 |
| 2014-04-09 08:39:59 | 0.210.243.93 | 0 |
| 2014-04-09 08:40:00 | 0.210.243.93 | 1 |

对于dIPaddr:0.210.25.224,它有,我们将其命名为table_224:

| 2014-04-09 13:02:25 | 0.210.25.224  |       3       |
| 2014-04-09 13:02:26 | 0.210.25.224 | 0 |
| 2014-04-09 13:02:27 | 0.210.25.224 | 1 |
+---------------------+---------------+---------------+

然后我想做:table_240.count+table_93.count+table_224.count,得到一个名为table_final的新表,但table_final中的记录数应为table_240、table_93和table_224中的最小条数。因此,table_final应该是:

+-------+
| count |
+-------+
| 6 |
| 0 |
| 3 |
+-------+
(6=2+1+3, 2 is the first record in table_240,1 is the first record in table_93,3 is the first record in table_224.)

(0=0+0+0, 0 is the second record in each of table_240,93,224)

(3=1+1+1, 1 is the third record in each of table_240,93,224)

我怎样才能获得 table_final ?

上面只是一个简单的例子,我的table1有570000条记录,超过5000个dIPaddr,每个dIPaddr有超过100条流记录(这意味着超过100条StartTime记录)。table_final应该保存的最小数量所有这些 table_dIPaddr 中的行。所以table_final可能有100行,或者200行,或者更多,这取决于这些table_dIPaddr中的最小行数是多少(在上面的例子中,table_240,table_93,table_224属于table_dIPaddr。Table_dIPaddr意味着计算行数,组表 1(按 dIPaddr、StartTime)。现在的情况是我只有 table1,我显示 table_240 , table_93 等只是为了解释我的需求。在表1中,有数千个dIPaddr,每个dIPaddr有超过100个流。如何通过 table1 获得 table_final ?

我想使用tally来获取table2,我有一些提示,但仍然不知道如何获取table2。我想如果我想获得table_final,我应该先获得表2,但我不知道如何获得表2。如果我只有一个 dIPaddr,我知道如何获取 table2,但我不知道如何获取具有不同 dIPaddr 的 table2。

这是mysql如何获取table2。(一些提示) how to count the num of records in a group in mysql

首先,我们需要创建计数:

CREATE TABLE tally(n INT NOT NULL AUTO_INCREMENT PRIMARY KEY);


INSERT INTO tally
SELECT a.N + b.N * 10 + c.N * 100 + d.N * 1000 + e.N * 10000 + 1 n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6) b
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 ) c
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) d
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) e

ORDER BY n;

(因为一天有24小时,所以记录数需要大于3600*24。)

然后我创建一个表,其中仅包含 0.210.208.240 的 Starttime 和 dIPaddr,将此表命名为:temp240,在 temp240 中,它有:

 +---------------------+---------------+
| StartTime | dIPaddr |
+---------------------+---------------+
| 2014-04-09 09:47:53 | 0.210.208.240 |
| 2014-04-09 09:47:53 | 0.210.208.240 |
| 2014-04-09 09:47:55 | 0.210.208.240 |
+---------------------+---------------+

然后创建一个名为test240的表,

insert into test240
SELECT b.starttime, COALESCE(count, 0) count
FROM
(
SELECT min_dt + INTERVAL n-1 SECOND starttime
FROM tally t CROSS JOIN
(
SELECT MIN(starttime) min_dt, MAX(starttime) max_dt
FROM temp240
WHERE starttime >= '2014-04-09'
AND starttime < '2014-04-09' + INTERVAL 1 DAY
) i
WHERE t.n-1 <= TIMESTAMPDIFF(SECOND, min_dt, max_dt)
) b LEFT JOIN
(
SELECT starttime, COUNT(*) count
FROM temp240
WHERE starttime >= '2014-04-09'
AND starttime < '2014-04-09' + INTERVAL 1 DAY
GROUP BY starttime
) q
ON b.starttime = q.starttime;

然后我得到 test240:

+---------------------+---------------+
| StartTime | count |
+---------------------+---------------+
| 2014-04-09 09:47:53 | 2 |
| 2014-04-09 09:47:54 | 0 |
| 2014-04-09 09:47:55 | 1 |
+---------------------+---------------+

但是我不知道如何获取table2,因为实际上table1包含数千个dIPaddr,我无法为每个dIPaddr创建数千个tempdIPaddr,然后获取其对应的testdIPaddr表。我不知道如何修改上面的mysql计算所有 dIPaddr。

最佳答案

首先,不要将每个 IP 地址放在不同的表中。将它们全部放在一个表中,按 dIPaddr、StartTime 分组。

确保此计数表具有自动递增 id 字段(例如 CountRowId),并且计数结果按 dIPaddr、StartTime 的顺序输入。

现在,再次按 dIPaddr(仅)分组,并查找每个 dIPaddr 的 CountRowId 值的最小值和最大值。

再添加一列(如 OrdinalWithinIP),并为每条记录将其设置为其 Max(CountRowId)(dIpaddr 减去 CountRowId)。对于每个 IPaddr,这将为您提供每个计数记录的序数,例如 1、2、3 等。

然后,按序数分组并求和。

关于mysql - 如何统计mysql中的记录数并添加它们?(使用tally),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28681662/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com