【问题标题】:Fuzzy grouping in PostgresPostgres 中的模糊分组
【发布时间】:2010-12-11 16:41:16
【问题描述】:

我有一个表格,其内容类似于:

id | title
------------
1  | 5. foo
2  | 5.foo
3  | 5. foo*
4  | bar
5  | bar*
6  | baz
6  | BAZ

……等等。我想按标题分组并忽略多余的部分。我知道 Postgres 可以做到这一点:

SELECT * FROM (
  SELECT regexp_replace(title, '[*.]+$', '') AS title
  FROM table
) AS a
GROUP BY title

但是,这很简单,如果我试图预测所有可能的变化,那将变得非常笨拙。所以,问题是,有没有比使用正则表达式更通用的方法来进行模糊分组?有没有可能,至少不伤筋动骨?

编辑:澄清一下,对任何变体都没有偏好,这是分组后表格的样子:

title
------
5. foo
bar
baz

即,变体将是仅由几个字符或大写字母不同的项目,只要将它们分组,剩下哪些并不重要。

【问题讨论】:

    标签: sql postgresql group-by fuzzy


    【解决方案1】:

    对于 any 分组,您应该具有传递相等性,即 a ~= b, b ~= c => a ~= c

    严格使用文字表述,我们将尝试使用SQL表述。

    例如,foo*bar 应该去哪个组?

    更新:

    此查询将所有非字母数字字符替换为空格并返回每个组的第一个标题:

    SELECT  DISTINCT ON (REGEXP_REPLACE(UPPER(title), '[^[:alnum:]]', '', 'g')) title
    FROM    (
            VALUES
            (1, '5. foo'),
            (2, '5.foo'),
            (3, '5. foo*'),
            (4, 'bar'),
            (5, 'bar*'),
            (6, 'baz'),
            (7, 'BAZ')
            ) rows (id, title)
    

    【讨论】:

    • 到它自己的组,因为它与其他项目不够相似。这就是为什么问题与模糊分组有关:行最终与哪个变体分组并不重要,重要的是它们是否被分组。
    • Reinis I.: 足够相似 通常是不可传递的,这意味着它不可分组。例如,如果foofor 足够相似并且forbar 足够相似,但foobar 不够相似,那么您无法建立任何组。
    • 我不是说可以做到,我是在问如何解决它。
    【解决方案2】:

    有时,您将不得不定义是什么让一组值属于一个组。如果这太难了,也许您应该禁止和禁止输入模糊数据,或者如果您必须允许,请添加一个包含经过清理的标题版本的列,以供分组操作使用。

    【讨论】:

      猜你喜欢
      • 2021-05-13
      • 2020-08-28
      • 2017-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-28
      • 1970-01-01
      相关资源
      最近更新 更多