2011-03-31 10 views
7

Estoy buscando soluciones MySQL y PostgreSQL para este tipo de problema.Ordenando alfabéticamente registros con "The", "A", "An", etc. al comienzo del campo varchar

Digamos que tengo una serie de registros con un campo title. Los títulos son títulos de libros o películas, como "El gato en el sombrero" y "Robin Hood". Pero aunque los títulos deben mostrarse en su forma original, deben ordenarse de la forma en que las bibliotecas los clasifican, lo cual es moviendo cualquier artículo, como "The" o "An" al final del título.

Por lo tanto, "The Cat in the Hat" está ordenado como si fuera "Cat in the Hat, The".

¿Cuál es la mejor forma de diseñar el esquema o escribir la consulta para que estos registros estén ordenados por título de la misma manera que las bibliotecas ordenan el título? (También me gustaría saber el término técnico para este tipo de ordenamiento por título.) Además, ¿qué consideraciones de rendimiento debería conocer y qué índices debería crear?

+0

Puede ser una buena idea tener el programa que está utilizando, escribirlo en la base de datos de esta manera. Otra opción sería crear otro "campo de clasificación" que esté ocupado por un desencadenante al ingresar un registro, y el desencadenador eliminaría estas palabras y las colocaría en el extremo para usted. – rayman86

+2

Personalmente, agregaría otra columna donde precalculo el título para ordenar por. Luego actualizaría esta columna, siempre que se modifique el título principal. Sería bastante rápido al ordenar, supongo. –

Respuesta

3

Cree una función personalizada que (¿tipo título, quizás?) Que modifique las cadenas que comiencen con sus palabras no deseadas. Complete su declaración de consulta con order by sortableTitle(title). Esto implicará un costo extra de CPU, aunque deberá compararlo para saber cuánto.

Puede crear una columna adicional (sortTitle) que se rellena con un desencadenador. Esto ocupará algo de espacio, pero luego su servidor podrá ordenar las filas por un índice.

Exceptuando lo anterior, no puede (sin modificar el código del servidor de la base de datos) crear directamente un índice que tenga el orden que desee. Por lo que puedo decir, eso se aplica tanto a MySQL como a PostgreSQL.

+2

Para PostgreSQL se puede crear un índice de la función para acelerar la ordenación: 'CREATE INDEX sort_index ON my_table (sortableTitle (title))' –

+0

¡Agradable! Una pregunta y voté una respuesta y dos comentarios que me dicen que estoy equivocado. ¡Buen consejo! –

1
Select * from TitleTable 
Order by 
Case when substring(title,0,4) = 'The ' then substring(title, 4, len(title)-4) 
when substring(title,0,3) = 'An ' then substring(title, 3, len(title)-3) 
when substring(title,0,2) = 'A ' then substring(title, 2, len(title)-2) 
else title 
end 
4

¿Por qué no sólo tiene que añadir un campo "title_prefix" a la mesa y se mueven todas estas "cadenas" y los "unos" hay? Cuando esté ordenando, usaría el campo "título", y cuando presente el título podría hacer la concatenación de la forma que desee.

+0

Diría +1/2, pero supongo que redondea hasta +1. Requiere modificar el código de inserción y crear una vista o modificar el código de consulta. Sin embargo, el tiempo de CPU para la vista no debería ser tan malo. Algo como 'concat (ifnull (prefix," ", concat (", ", prefix), title)' haría para ese campo en una vista. –

+1

O con una llamada en concat: 'ifnull (prefix, title, concat (título, ",", prefijo)) ' –

1

Le sugiero que divida el campo title en dos campos: mainTitle y pre.

Cuando se agrega un título, compruebe si comienza con "A", "El" u otros prefijos y divídalo (quizás con un desencadenador) en los dos campos. Su tabla se vería así:

| pre | mainTitle | 
|-----|----------------| 
| The | Cat in the Hat | 
| A | Space Odyssey | 
|  | Eyes Wide Shut | 

lo tanto, puede tener un índice en el campo mainTitle y utilizarlo para la clasificación.

Cuando desee mostrar el título completo, concat los dos campos, en cualquiera de los dos formularios.


  • Si elige esta manera, usted tiene que modificar en consecuencia el código cuando un usuario da un título para buscar en la tabla. El título dado deberá dividirse de la misma manera antes de buscar en el campo mainTitle.

  • Deberá tener mucho, mucho cuidado con el código (desencadenador u otro) que realiza la división para que algunos casos especiales se capturen correctamente.Usted no quiere tener la A = B o los libros A B C: learn the alphabet muestran y se ordenan como = B, A y B C: learn the alphabet, A

2

iTunes logra esto a través de un segundo campo en el que el título se almacena en el formato deseado de clasificación y la clasificación en esta en lugar de título Suena como una salida barata, pero cuando se consideran las implicaciones de rendimiento de hacer manipulaciones de cadenas en cada título cada vez que se hace una instrucción select que ordena por título, contra manipulaciones de cadena cada vez que insertas o actualizas el título, lo hace tener sentido.

Cuestiones relacionadas