这出现了很多,我可以看到它出现在XSLT,Ruby和Drupal的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大师权衡其中有性能影响。
答案 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, '的', ''), '一个\'”, ''), '一个', '')
未经测试!