2010-07-15 21 views
8

Điều này xuất hiện rất nhiều và tôi có thể thấy nó xuất hiện trên StackOverflow cho XSLT, RubyDrupal nhưng tôi không ' t thấy nó đặc biệt cho SQL.Cách sắp xếp trong SQL, bỏ qua các bài viết ('the', 'a', "an", v.v.)

Vì vậy, câu hỏi đặt ra là, làm cách nào để bạn sắp xếp tiêu đề chính xác khi bắt đầu bằng "The", "A" hoặc "An"?

Một cách đơn giản là để TRIM() những chuỗi:

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

đó là suggested on AskMeFi một khi trở lại (hiện nó cần mà LOWER() chức năng?).

Tôi biết tôi cũng đã thấy một số loại trường hợp/Chuyển đổi triển khai thực hiện điều này nhưng hơi khó để Google cho.

Rõ ràng có một số giải pháp khả thi. Điều gì sẽ là tốt rất kinh nghiệm SQL có trọng lượng trong đó có ý nghĩa hiệu suất.

+0

Đồng ý với người nhận xét về một câu hỏi SO được liên kết: quy tắc có thể trở nên phức tạp hơn. Ví dụ, đề xuất cụ thể của bạn có thể sẽ không sắp xếp đúng danh sách sau: 'The A Test',' The B Test', 'The C Test'. –

Trả lời

6

Một cách tiếp cận tôi đã nhìn thấy là có hai cột - một cho hiển thị và người kia để phân loại:

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

tôi đã không thực hiện bất kỳ thử nghiệm thế giới thực, nhưng điều này có lợi ích của việc có thể để sử dụng chỉ mục và không yêu cầu thao tác chuỗi mỗi khi bạn muốn đặt hàng theo mô tả. Trừ khi cơ sở dữ liệu của bạn hỗ trợ các khung nhìn vật chất (mà MySQL không), việc thực hiện logic như một cột được tính trong một khung nhìn sẽ không cung cấp bất kỳ lợi ích nào vì bạn không thể lập chỉ mục cột được tính toán.

0

Tôi chỉ có thể nói cho SQL Server: bạn sử dụng LTRIM trong các câu lệnh CASE. Không cần hàm LOWER vì các lựa chọn không phân biệt chữ hoa chữ thường theo mặc định. Tuy nhiên, nếu bạn muốn bỏ qua các bài viết thì tôi khuyên bạn nên sử dụng từ điển từ tiếng ồn và thiết lập một danh mục chỉ mục toàn văn. Tôi không chắc liệu các triển khai khác có hỗ trợ SQL không.

+0

Độ nhạy trường hợp phụ thuộc vào đối chiếu. Tìm kiếm văn bản đầy đủ (FTS) có sẵn trên MySQL, Oracle, SQL Server ... Dunno những gì PostgreSQL là nhưng tôi chắc chắn nó có chức năng bản địa. Và có FTS của bên thứ 3 như nhân sư ... –

+0

"bạn sử dụng LTRIM trong câu lệnh CASE" - điều này có nghĩa là bạn làm tương đương với "nếu nó bắt đầu bằng ',' cắt nó"? Tôi đã tự hỏi liệu điều đó có làm chậm quá trình xuống, trái ngược với một tấm chăn TRIM() mà có thể thất bại phần lớn thời gian. – AmbroseChapel

+0

LTRIM loại bỏ các không gian hàng đầu – CarneyCode

-1

LOWER là cần thiết. Trong khi SELECT không phân biệt chữ hoa chữ thường, thì ORDER BY là.

-3

Hãy thử như sau:

ORDER BY thay thế (thay thế (thay thế (YOURCOLUMN, 'THE', ''), 'a \'', ''), 'an', '')

Không được kiểm tra!

+1

Ngạc nhiên không ai giải thích vấn đề với điều này. Khi sắp xếp, bạn muốn thay thế các bài viết LEADING, trong khi điều này sẽ thay thế TẤT CẢ các bài viết. –

2

Tôi đã sử dụng này trong nhiều năm, nhưng không thể nhớ nơi tôi tìm thấy nó:

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 

yielding:

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

Đối với Postgres cụ thể, bạn có thể sử dụng để làm regexp_replace phù hợp với bạn:

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; 
Các vấn đề liên quan