7

询问

SELECT COUNT(*), name, number
FROM   tbl
GROUP  BY name, number
HAVING COUNT(*) > 1

它有时无法找到小写和大写之间的重复项。
例如:sunny并且Sunny不要显示为重复项。
那么如何在 PostgreSQL 中为两列找到所有可能的重复项。

4

3 回答 3

18

lower()/upper()

使用其中之一将字符折叠为小写或大写。特殊字符不受影响:

SELECT count(*), lower(name), number
FROM   tbl
GROUP  BY lower(name), number
HAVING count(*) > 1;

unaccent()

如果你真的想忽略变音符号,就像你的评论暗示的那样,安装附加模块unaccent,它提供了一个删除重音的文本搜索字典以及通用功能unaccent()

CREATE EXTENSION unaccent;

使它非常简单:

SELECT lower(unaccent('Büßercafé'));

结果:

busercafe

这不会去除非字母。添加regexp_replace()像@Craig提到的那样:

SELECT lower(unaccent(regexp_replace('$s^o&f!t Büßercafé', '\W', '', 'g') ));

结果:

softbusercafe

您甚至可以在此基础上构建功能索引:

于 2012-10-19T17:36:25.693 回答
4

默认情况下,PostgreSQL 区分大小写。您可以通过将所有值转换为单个大小写来强制它在搜索期间不区分大小写:

SELECT COUNT(*), lower(name), number FROM TABLE 
GROUP BY lower(name), number HAVING COUNT(*) > 1
  • 注意:这还没有在 Postgres 中测试过
于 2012-10-19T17:36:38.780 回答
1

(从海报澄清后更新的答案):“不重音”或剥离重音(dicratics)的想法通常是虚假的。résumé如果您正在匹配数据以找出是否有误入歧途的用户或应用程序,这没关系resume,但是将一个更改为另一个是完全错误的,因为它们是不同的词。即使那样,它也只是一种工作,并且应该与字符串相似性匹配系统(如trigramsLevenshtein distances )结合使用。

“非重音”的概念假定任何重音字符都具有一个有效的等效非重音字符,或者至少任何给定的重音字符在单词的 ascii-ized 表示中最多被一个非重音字符替换。这根本不是真的。在一种语言中ö可能是“u”音,而在另一种语言中可能是长“oo”,而“ascii-ized”拼写约定可能反映了这一点。因此,在语言中,虚构的虚拟词“Tapö”的正确“非重音”可能是“Tapu”,而在另一种情况下,这个虚构的词可能被 ascii-ized 为“Tapoo”。在这两种情况下,“Tapo”的“非重音”形式都不会与人们在强制使用 ascii 字符集时实际编写的内容相匹配。

你可以用连字的英文看到这个dæmon,其中单词是 ascii-ized daemon。如果你去掉连字,你会得到dmonwhich would not match daemon,常见的拼写。这同样适用于æther它通常被asciiized to aetheror ether。您也可以使用ß在德语中看到这一点,通常“扩展”为ss

如果您必须尝试“取消重音”、“规范化”重音或“剥离”重音:

您可以使用字符类正则表达式去除除指定字符集之外的所有字符。在这种情况下,我们使用转义符(根据手册\W中字符类的简写)来排除“符号”,但不排除重音字符:[^[:alnum:]_]

regress=# SELECT regexp_replace(lower(x),'\W','','g') 
          FROM ( VALUES ('$s^o&f!t'),('Café') ) vals(x);
 regexp_replace 
----------------
 soft
 café
(2 rows)

如果您也想过滤掉重音字符,您可以定义自己的字符类:

regress=# SELECT regexp_replace(lower(x),'[^a-z0-9]','','g')
          FROM ( VALUES ('$s^o&f!t'),('Café') ) vals(x);
 regexp_replace 
----------------
 soft
 caf
(2 rows)

如果您实际上打算一些重音字符替换类似的非重音字符,则可以translate按照此 wiki 文章使用:

regress=# SELECT translate(
        lower(x),
        'âãäåāăąÁÂÃÄÅĀĂĄèééêëēĕėęěĒĔĖĘĚìíîïìĩīĭÌÍÎÏÌĨĪĬóôõöōŏőÒÓÔÕÖŌŎŐùúûüũūŭůÙÚÛÜŨŪŬŮ',
        'aaaaaaaaaaaaaaaeeeeeeeeeeeeeeeiiiiiiiiiiiiiiiiooooooooooooooouuuuuuuuuuuuuuuu'
    )
    FROM ( VALUES ('$s^o&f!t'),('Café') ) vals(x);

 translate 
-----------
 $s^o&f!t
 cafe
(2 rows)
于 2012-10-22T11:08:01.863 回答