una - restriccion check sql server
Encuentra posibles duplicados en dos columnas ignorando mayúsculas y minúsculas y caracteres especiales (3)
PostgreSQL por defecto distingue entre mayúsculas y minúsculas. Puede forzarlo a que no distinga entre mayúsculas y minúsculas durante las búsquedas convirtiendo todos los valores en un solo caso:
SELECT COUNT(*), lower(name), number FROM TABLE
GROUP BY lower(name), number HAVING COUNT(*) > 1
- NOTA : Esto no ha sido probado en Postgres
Consulta
SELECT COUNT(*), name, number
FROM tbl
GROUP BY name, number
HAVING COUNT(*) > 1
A veces no encuentra duplicados entre mayúsculas y minúsculas.
Por ejemplo: sunny
y Sunny
no aparecen como duplicados.
Entonces, ¿cómo encontrar todos los duplicados posibles en PostgreSQL para dos columnas?
(Respuesta actualizada después de la aclaración del póster): la idea de "desestimar" o quitar acentos (dicráticos) es generalmente falsa. Está bien, si estás combinando datos para averiguar si algún usuario o aplicación equivocado envió un résumé
a la resume
, pero es totalmente incorrecto cambiar uno por el otro, ya que son palabras diferentes. Incluso entonces solo funcionará, y debería combinarse con un sistema de coincidencia de semejanzas de cuerdas como trigramas o distancias de Levenshtein .
La idea de "dejar de prestar" presupone que cualquier carácter acentuado tiene un único carácter válido sin carácter acentuado o, al menos, que cualquier carácter acentuado dado se sustituye por un carácter sin acentos como máximo en una representación asciiizada de la palabra. Eso simplemente no es verdad; en un idioma, podría ser un sonido "u", mientras que en otro podría ser un "oo" largo, y las convenciones de ortografía "ascii-izadas" podrían reflejar eso. Por lo tanto, en el lenguaje, el "desacentuación" correcto de la palabra fingida inventada "Tapö" podría ser "Tapu" y en otro esta palabra imaginaria podría ser asimilada a "Tapoo". En ninguno de los dos casos, la forma "sin acentos" de "Tapo" concuerda con lo que las personas realmente escriben cuando son forzados al conjunto de caracteres ascii. Las palabras con dicráticos también pueden ser asimiladas en una palabra con guiones.
Puedes ver esto en inglés con ligatures, donde la palabra dæmon
es daemon
ascii -ized. Si dmon
la ligadura obtendrías dmon
que no coincidiría con daemon
, la ortografía común. Lo mismo es cierto para æther
que normalmente se æther
a aether
o ether
. También puede ver esto en alemán con ß , generalmente "expandido" como ss
.
Si debe intentar "acentuar", "normalizar" acentos o acentos de "tira":
Puede usar una expresión regular de clase de caracteres para eliminar todo excepto un conjunto de caracteres especificado. En este caso usamos el escape /W
(abreviatura de la clase de caracteres [^[:alnum:]_]
según el manual ) para excluir "símbolos" pero no caracteres acentuados:
regress=# SELECT regexp_replace(lower(x),''/W'','''',''g'')
FROM ( VALUES (''$s^o&f!t''),(''Café'') ) vals(x);
regexp_replace
----------------
soft
café
(2 rows)
Si desea filtrar los caracteres acentuados también puede definir su propia clase de caracteres:
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)
Si realmente pretendía sustituir algunos caracteres acentuados por caracteres sin acentos similares, podría usar translate
según este artículo wiki :
regress=# SELECT translate(
lower(x),
''âãäåāăąÁÂÃÄÅĀĂĄèééêëēĕėęěĒĔĖĘĚìíîïìĩīĭÌÍÎÏÌĨĪĬóôõöōŏőÒÓÔÕÖŌŎŐùúûüũūŭůÙÚÛÜŨŪŬŮ'',
''aaaaaaaaaaaaaaaeeeeeeeeeeeeeeeiiiiiiiiiiiiiiiiooooooooooooooouuuuuuuuuuuuuuuu''
)
FROM ( VALUES (''$s^o&f!t''),(''Café'') ) vals(x);
translate
-----------
$s^o&f!t
cafe
(2 rows)
lower()
/ upper()
Use uno de estos para doblar caracteres en mayúscula o minúscula. Los caracteres especiales no se ven afectados:
SELECT count(*), lower(name), number
FROM tbl
GROUP BY lower(name), number
HAVING count(*) > 1;
unaccent()
Si realmente desea ignorar los signos diacríticos, como lo implican sus comentarios, instale el módulo adicional unaccent
, que proporciona un diccionario de búsqueda de texto que elimina los acentos y también la función de propósito general unaccent()
:
CREATE EXTENSION unaccent;
Lo hace muy simple:
SELECT lower(unaccent(''Büßercafé'')) AS norm
Resultado:
busercafe
Esto no elimina las letras no. Agregue regexp_replace()
como @Craig mencionado para eso:
SELECT lower(unaccent(regexp_replace(''$s^o&f!t Büßercafé'', ''/W'', '''', ''g'') ))
AS norm
Resultado:
softbusercafe
Incluso puedes construir un índice funcional además de eso: