如何在SQL中排序,忽略文章('the“,”a“,”an“等)

时间:2010-07-15 05:00:01

标签: sql mysql sorting switch-statement trim

这出现了很多,我可以看到它出现在XSLTRubyDrupal的StackOverflow上,但我没有专门针对SQL。

所以问题是,当你以“The”,“A”或“An”开头时,如何正确地对标题进行排序?

一种方法就是TRIM()那些字符串:

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

前一段时间是suggested on AskMeFi(是否需要LOWER()函数?)。

我知道我也看到过某种Case / Switch实现方式,但对谷歌来说有点困难。

显然,有许多可能的解决方案。什么是好的是SQL大师权衡其中有性能影响。

6 个答案:

答案 0 :(得分:6)

我见过的一种方法是有两列 - 一列用于显示,另一列用于排序:

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

我还没有进行任何真实世界的测试,但这样做的好处是能够使用索引,并且每次要按描述排序时都不需要字符串操作。除非您的数据库支持物化视图(MySQL不支持),否则在视图中将逻辑实现为计算列将不会提供任何好处,因为您无法索引计算列。

答案 1 :(得分:2)

我多年来一直在使用它,但不记得我发现它的位置:

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 

产量:

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

答案 2 :(得分:0)

我只能代表SQL Server:您在CASE语句中使用LTRIM。不需要LOWER功能,因为默认情况下选择不区分大小写。但是,如果你想忽略文章,那么我建议你使用一个干扰词字典并设置一个全文索引目录。我不确定其他实现是否支持SQL。

答案 3 :(得分:0)

对于Postgres,您可以使用regexp_replace为您完成工作:

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;

答案 4 :(得分:-1)

LOWER是必需的。虽然SELECT不区分大小写,但ORDER BY是。

答案 5 :(得分:-3)

尝试以下方法:

ORDER BY 更换(更换(替换(YOURCOLUMN, '的', ''), '一个\'”, ''), '一个', '')

未经测试!