【问题标题】:merge mysql rows by name when names are slightly different当名称略有不同时,按名称合并mysql行
【发布时间】:2015-05-04 16:15:34
【问题描述】:

我正在尝试使用以下代码合并 MySQL 中的行:

SELECT
    type,
    name,
    GROUP_CONCAT(code SEPARATOR ',') AS code
FROM
    `table1`
WHERE
    name = '%name%' AND type = 'type'
GROUP BY
    name

但是数据库条目没有发生变化,这是第一个问题。

数据库如下所示:

type | name  | code
-----|-------|-------
 A   | Milk2 | 143521
-----|-------|-------
 A   | Milk3 | 987564
-----|-------|-------
 B   | Oil   | 656435
-----|-------|-------

我想让它看起来像:

type | name  | code
-----|-------|---------------
 A   | Milk  | 143521, 987564
-----|-------|---------------
 B   | Oil   | 656435
-----|-------|---------------

如您所见,名称可能略有不同,因此这是另一个问题。 我想知道是否有任何方法可以合并行,比如名称的前四个字母匹配?

提前致谢。

【问题讨论】:

    标签: mysql merge rows


    【解决方案1】:

    MySQL 有几个string functions 可能会有所帮助。有 LEFT(name, 4),您可能还想查看 SOUNDEX(name),它实现了 Soundex algorithm 来散列听起来相似的单词。例如:

     select soundex('smith'), soundex('smythe')
    
    + --------------------- + ---------------------- +
    | soundex('smith')      | soundex('smythe')      |
    + --------------------- + ---------------------- +
    | S530                  | S530                   |
    + --------------------- + ---------------------- +
    1 rows
    

    或者,使用您问题中的示例:

    select soundex('milk2'), soundex('milk3')
    
    + --------------------- + --------------------- +
    | soundex('milk2')      | soundex('milk3')      |
    + --------------------- + --------------------- +
    | M420                  | M420                  |
    + --------------------- + --------------------- +
    1 rows
    

    您的查询将如下所示:

    SELECT
        type,
        GROUP_CONCAT(DISTINCT(name) SEPARATOR ',') AS name,  // note that since you've grouped on SOUNDEX(name) you can't just select name (MySQL may let you but will choose the first one
        GROUP_CONCAT(code SEPARATOR ',') AS code
    FROM
        `table1`
    WHERE
        name LIKE '%name%' AND type = 'type'
    GROUP BY
        type, SOUNDEX(name)
    

    希望对你有帮助!

    【讨论】:

    • SOUNDEX 在这里效果最好。据我检查没有错误。我唯一无法解决的问题是,当“石油”同时属于 A 型和 B 型时,代码不会合并。
    • 如果您不需要合并集中的类型值,您可以将其省略 - 或者,如果您确实需要类型值,您希望将哪个类型与合并结果相关联?如果您不太在意选择了哪个值,只需将“类型”从组中排除,MySQL 将(与 SQL 规范相反...)选择一个值。我不确定它是选择它遇到的第一个还是什么,但这可能有效。
    【解决方案2】:

    这里不能使用GROUP BY name,因为名称总是不同的,使用通配符时需要使用LIKE而不是=

    以下内容应为您提供所需的结果

    SELECT 
     type , name, GROUP_CONCAT( code SEPARATOR  ',' ) AS all_codes
    FROM  `table1` 
    name LIKE '%name%' AND type = 'type'
    

    【讨论】:

    • 这错过了 OP 请求的重点 - 例如,将 milk2 和 milk3 放入同一个桶中。
    • 我在类似数据上测试了这个查询,它准确地抛出了他正在寻找的结果
    • 遗憾的是,当有大量数据时,“LIKE”似乎无法正常工作。它倾向于合并许多与错误名称相对应的代码。也可能是我做错了什么……
    • 如果您想在名称字段的开头使用名称,您可以使用LIKE 'name%',或者如果您想将名称作为不是第一个单词的单词的开头,请使用LIKE '% name%'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    相关资源
    最近更新 更多