MySQL查询:在一个非常大的表中计算重复值

MySQL查询:在一个非常大的表中计算重复值,mysql,select,count,Mysql,Select,Count,我有一张MySQL表: CREATE TABLE `triple` ( `id_one` int(11) NOT NULL, `id_two` int(11) NOT NULL, `id_three` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 它包含近1000万行。中间列ID2的ID可以出现在不同行的不同时间。 简短示例: id_one id_two

我有一张MySQL表:

CREATE TABLE `triple` (
  `id_one` int(11) NOT NULL,
  `id_two` int(11) NOT NULL,
  `id_three` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
它包含近1000万行。中间列ID2的ID可以出现在不同行的不同时间。 简短示例:

id_one    id_two    id_three
1         2         3
2         2         3
3         2         1
68        98        1
1         4         3
2         4         4
4         5         33
6         5         3
90        5         3
34        5         83
9         3         98
现在我想计算不同的id_2,即在本例中:

id_two     count
2     ->  3
98    ->  1
4     ->  2
5     ->  4
3     ->  1
如何有效地实现这一目标?这是一个一次性的工作。。。这是第一件事。我需要做的第二件事是:像上面那样进行计数,然后只选择那些计数超过100的ID

非常感谢你的帮助

问候
Aufwind

完成此任务的基本命令如下:

SELECT id_two, count(*) FROM triple GROUP BY id_two;
如果您想

CREATE TEMPORARY TABLE xxx SELECT id_two, count(*) AS c FROM …
SELECT * FROM xxx WHERE c > 100;
…或在外部查询中使用结果

SELECT * FROM (SELECT id_two, count(*) AS c FROM triple GROUP BY id_two) t WHERE c > 100;
…或使用Marc在评论中建议的HAVING子句:

SELECT id_two, count(*) AS c FROM triple GROUP BY id_two HAVING c > 100;
试试这个:

select id_two,Frequency=count(*)
from triple
group by id_two
having count(*) > 1 -- replace 1 with desired threshold
关于问题1:

SELECT id_two, COUNT(1)
  FROM triple
GROUP BY id_two
关于问题2:

SELECT id_two, COUNT(1)
  FROM triple
GROUP BY id_two
HAVING COUNT(1) > 100

第二件事,使用

SELECT id_two, count(*) nb FROM triple GROUP BY id_two HAVING nb >= 100;

索引字段id\u two应该会提高性能。

对于1000万行表上的一次性作业,我只需完全跳过SQL即可。尝试使用GROUP BY可能会将您的表锁定太长时间

SELECT id_two FROM TRIPLE INTO OUTFILE('/tmp/idtwo.txt')
在类Unix系统上,这将生成一个包含两列的列表:出现次数、ID

# sort -n /tmp/idtwo.txt | uniq -c

…如果必须使用GROUP BY,请在select语句末尾添加ORDER BY NULL以节省时间。否则MySQL将尝试按id\u two的值对您的组进行排序。

假设您在id\u two列上有一个索引,这也应该很快。这容易吗?我很惭愧。。。我没有id上的索引。我最好创建一个吗?嗯,为什么不使用having子句呢?选择id_two,按cnt>100的id_two从行程组中将*计为cnt。没有临时表,没有子选择…@Marc B:只是想表明,在没有临时表的情况下,可以对结果集执行任意操作。更新答案以保持其完整性。谢谢!不幸的是,这将在“字段列表”错误中给出一个1054-未知列“频率”。。。也许将*计算为频率?您可以选择您喜欢的语法。mySql不支持column name=value语法吗?我更喜欢column name=value,因为它比真正的长ginormous表达式“作为列名”更易于阅读代码。不幸的是,MySQL不支持这种语法。检查也许在他们的bug追踪器中提交一个功能请求。谢谢你提示按NULL订购。
# sort -n /tmp/idtwo.txt | uniq -c