按类似字符串分组

时间:2013-11-26 16:46:13

标签: mysql sql group-by case

假设我有一个这样的表

| id_grupo |    nombre       |
|:---------|----------------:|
| 1        | Emprendedores 1 |     
| 2        | Emprendedores 2 |    
| 3        | Emprendedoras 1 |      
| 4        | Emprendedoras 2 |         
| 5        | Los amigos 1    |       
| 6        | Los amigos 2    |
| 7        | Los amigos no 1 |  

我希望按名称分组相同但结束的号码不同。如果仔细观察,有两个或更多单词组成的名称,但不同之处在于结尾。还有一些名字看起来相似,但它们不一样,如“洛杉矶朋友”和“洛杉矶阿米戈斯”,这些属于不同的群体,“Emprendedores”和“Emprendedoras”也不同。

这是我的查询:

SELECT *, GROUP_CONCAT(id_grupo) 
FROM creabien_sacredi_dev.grupos
GROUP BY SUBSTRING(nombre,1,5)

它适用于大多数记录,但是问题来自于示例中非常相似的字符串。我选择一个包含5个字符的子字符串,但事实上名称长度不一样,所以有些字符串没有按预期工作。

如何以下列形式对这些字符串进行分组?

    | id_grupo |    nombre       | GROUP_CONCAT(id_grupo) |
    |:---------|----------------:|-----------------------:|
    | 1        | Emprendedores 1 |  1,2                   |    
    | 3        | Emprendedoras 1 |  3,4                   |   
    | 5        | Los amigos 1    |  5,6                   |
    | 7        | Los amigos no 1 |  7                     |

我认为关键是前一个字符串必须完全相同的最后一个数字,但我不知道该怎么做。你能帮帮我吗?

修改

还有像'Emprendedores'这样的记录,最后没有任何数字,这也应该与'Emprendedores 1'和'Emprendedores 2'组合在一起。所以我认为这个数字不再是关键,事实上我怀疑是否存在对这些记录进行分组的方法。

3 个答案:

答案 0 :(得分:3)

以下内容如何:

SELECT CASE 
         WHEN RIGHT(nombre, 1) BETWEEN '0' AND '9' THEN 
         LEFT(nombre, Length(nombre) - 2) 
         ELSE nombre 
       END AS nombrechecked, 
       Group_concat(id_grupo) 
FROM   grupos 
GROUP  BY 1 

以下SQL Fiddle表明它有效。

答案 1 :(得分:1)

如果要剪切的项目仅为数字且它们始终用空格分隔:

 SELECT CASE nombre REGEXP '[0-9]$'
        WHEN 1 THEN REVERSE (SUBSTR(REVERSE(nombre), 
                              INSTR(REVERSE(nombre),' '))) ELSE nombre END grupo, 
        GROUP_CONCAT(id_grupo)    
   FROM grupos
  GROUP BY grupo;

只是提案...... :)可能不是最高效的。优点是,它最终也可以使用更大的数字。

查看this Fiddle

答案 2 :(得分:0)

如果您没有“Los 2 amigos 1”等条目,那么

SELECT *, GROUP_CONCAT(id_grupo) 
FROM creabien_sacredi_dev.grupos
GROUP BY --replace digits with spaces
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE(
nombre,
'0',' '),'1',' '),'2',' '),'3',' '),'4',' '),'5',' '),'6',' '),'7',' '),'8',' '),'9',' ')