0

我有表:

Name     GroupID    etc...
ABC
ABC
DEF
DEF
DEF
KKK
LLL
III
III

我想要一个 PHP/MYSQL 组合来处理这个:

Name     GroupID    etc...
ABC       1
ABC       1
DEF       2 
DEF       2
DEF       2
KKK       0
LLL       0
III       3 
III       3

IE。如果该行存在具有重复名称的条目(完全匹配字符串),它将为具有该名称的所有条目分配一个 GroupID(自动递增)。如果条目是唯一名称,它将为 GroupID 分配一个 0

我的表有 250,000 个条目,实现这一目标的最快方法是什么?工作代码会很好,但高级算法足以让我继续前进。

谢谢!

4

1 回答 1

1

这可以通过一个快速的 PHP 脚本来完成,但我喜欢让数据库自己处理它的想法。

您可能可以通过巧妙的UPDATE连接来做到这一点,但是因为我无法测试它,所以我将使用临时表来代替。这个想法是选择所有Name计数 > 1 的值,并将行号分配给临时表。然后使用更新连接来修改原始表中的 GroupID。

SET @rownum=0;

CREATE TEMPORARY TABLE groupnums (groupid INT, Name VARCHAR(16), numgroups INT)
  SELECT
    @rownum := @rownum + 1 AS groupid, 
    Name,  
    COUNT(*) AS numgroups 
  FROM original_table 
  GROUP BY Name
  HAVING COUNT(*) > 1

UPDATE 
  original_table
  JOIN groupnums ON original_table.Name = groupnums.Name
SET original_table.GroupID = groupnums.groupid

然后将其余的设置为0

UPDATE original_table SET GroupID='0' WHERE GroupID IS NULL

并摆脱临时表。

DROP TABLE groupnums;

更新:

在为自己快速测试后,我发现虽然它有效,但您不会直接获得groupid. 为每一行而@rownum不是每组递增,因此您最终会得到如下组,其间有间隙。

/* Sample results - groups work, but have gaps between GroupID */
Name     GroupID    etc...
ABC       1
ABC       1
DEF       3
DEF       3
DEF       3
KKK       0
LLL       0
III       6 
III       6

更新 2 我有点过于复杂了。

深思熟虑后,@rownum根本不需要。只需在临时表中使用自动增量 ID。这应该会产生增量GroupID,而两者之间没有差距。使用与上述相同的UPDATE语句来反对这一点。

CREATE TEMPORARY TABLE groupnums (groupid INT NOT NULL AUTO_INCREMENT, Name VARCHAR(16), numgroups INT)
  SELECT 
    NULL AS groupid
    Name,
    COUNT(*) AS numgroups
  FROM original_table
  GROUP BY Name
  HAVING COUNT(*) > 1
于 2012-06-27T22:32:27.513 回答