2010-07-15 15 views
8

Esto aparece mucho, y puedo ver que ha aparecido en StackOverflow para XSLT, Ruby y Drupal pero no lo hago lo veo específicamente para SQL.Cómo ordenar en SQL, ignorando artículos ('el', '', '', etc.)

Entonces la pregunta es, ¿cómo se ordenan los títulos correctamente cuando comienzan con "The", "A" o "An"?

Una forma es simplemente para TRIM() esas cadenas:

ORDER BY TRIM( 
    LEADING 'a ' FROM 
    TRIM( 
    LEADING 'an ' FROM 
    TRIM( 
     LEADING 'the ' FROM LOWER(title) 
    ) 
    ) 
) 

que era suggested on AskMeFi hace un tiempo (¿Es necesario que la función LOWER()?).

Sé que también he visto algún tipo de implementación Case/Switch de esto, pero es un poco difícil de encontrar para Google.

Obviamente hay varias soluciones posibles. Lo que sería bueno es que los gurús de SQL tengan en cuenta las implicaciones del rendimiento.

+0

De acuerdo con un comentarista en una de las preguntas SO relacionadas: las reglas pueden resultar más complicadas de lo que parece. Por ejemplo, su sugerencia particular probablemente no clasifique correctamente la siguiente lista: 'The A Test',' The B Test', 'The C Test'. –

Respuesta

6

Un enfoque que he visto era tener dos columnas - uno para la pantalla y el otro para la clasificación:

description | sort_desc 
---------------------------- 
The the  | the, The 
A test   | test, A 
I, Robot  | i, Robot 

no he hecho ninguna prueba en el mundo real, pero esto tiene la ventaja de poder para usar un índice y no requiere manipulación de cadenas cada vez que desee ordenar por la descripción. A menos que su base de datos sea compatible con vistas materializadas (lo que MySQL no hace), implementar la lógica como una columna calculada en una vista no proporcionaría ningún beneficio porque no puede indexar la columna calculada.

0

Solo puedo hablar sobre SQL Server: utiliza LTRIM dentro de las sentencias CASE. No se necesita ninguna función INFERIOR porque las selecciones no distinguen entre mayúsculas y minúsculas por defecto. Sin embargo, si desea ignorar artículos, le sugiero que use un diccionario de palabras irrelevantes y configure un catálogo de indexación de texto completo. No estoy seguro si otras implementaciones son compatibles con SQL esto.

+0

La sensibilidad de mayúsculas y minúsculas depende de la intercalación. Full Text Search (FTS) está disponible en MySQL, Oracle, SQL Server ... No sé qué es PostgreSQL, pero estoy seguro de que tiene una funcionalidad nativa. Y hay FTS de terceros como la esfinge ... –

+0

"utiliza LTRIM dentro de las sentencias CASE": ¿significa esto que hace el equivalente a "si comienza con 'el', recorte?" Me preguntaba si eso desaceleraría el proceso, en contraposición a un TRIM global() que podría estar fallando la mayor parte del tiempo. – AmbroseChapel

+0

LTRIM se deshace de los espacios iniciales – CarneyCode

-1

LOWER es necesario. Mientras que SELECT no distingue entre mayúsculas y minúsculas, ORDER BY es.

-3

Pruebe lo siguiente:

ORDER BY replace (sustituir (reemplazar (YOURCOLUMN, 'LA', ''), 'a \'', ''), 'un', '')

¡No probado!

+1

Sorprendido, nadie ha explicado el problema con esto. Al ordenar, desea reemplazar artículos LEADING, mientras que esto reemplazará TODOS los artículos. –

2

He estado usando durante años, pero no puedo recordar dónde lo encontré:

SELECT 
CASE 
    WHEN SUBSTRING_INDEX(Title, ' ', 1) IN ('a', 'an', 'the') 
    THEN CONCAT(SUBSTRING(Title, INSTR(Title, ' ') + 1), ', ', SUBSTRING_INDEX(Title, ' ', 1)) 
    ELSE Title 
    END AS TitleSort, 
Title AS OriginalTitle 
FROM yourtable 
ORDER BY TitleSort 

Rendimiento:

TitleSort     | OriginalTitle 
------------------------------------------------------ 
All About Everything  | All About Everything 
Beginning Of The End, The | The Beginning Of The End 
Interesting Story, An  | An Interesting Story 
Very Long Story, A   | A Very Long Story 
0

Para Postgres específicamente, se puede utilizar para hacer el REGEXP_REPLACE trabaje para usted:

BEGIN; 
CREATE TEMPORARY TABLE book (name VARCHAR NOT NULL) ON COMMIT DROP; 
INSERT INTO book (name) VALUES ('The Hitchhiker’s Guide to the Galaxy'); 
INSERT INTO book (name) VALUES ('The Restaurant at the End of the Universe'); 
INSERT INTO book (name) VALUES ('Life, the Universe and Everything'); 
INSERT INTO book (name) VALUES ('So Long, and Thanks for All the Fish'); 
INSERT INTO book (name) VALUES ('Mostly Harmless'); 
INSERT INTO book (name) VALUES ('A book by Douglas Adams'); 
INSERT INTO book (name) VALUES ('Another book by Douglas Adams'); 
INSERT INTO book (name) VALUES ('An omnibus of books by Douglas Adams'); 

SELECT name FROM book ORDER BY name; 
SELECT name, regexp_replace(lower(name), '^(an?|the) (.*)$', '\2, \1') FROM book ORDER BY 2; 
SELECT name FROM book ORDER BY regexp_replace(lower(name), '^(an?|the) (.*)$', '\2, \1'); 
COMMIT; 
Cuestiones relacionadas