В алфавитном порядке записи с "The", "A", "An" и т. Д. В начале поля varchar - PullRequest
7 голосов
/ 31 марта 2011

Я ищу как MySQL, так и PostgreSQL решения для такого рода проблем.

Скажем, у меня есть несколько записей с полем title. Названия книг или фильмов, такие как «Кот в шляпе» и «Робин Гуд». Но хотя заголовки должны отображаться в их первоначальном виде, их следует сортировать так, как их сортируют библиотеки, то есть путем перемещения любой статьи, например «The» или «An», в конец заголовка.

Таким образом, «Кот в шляпе» отсортирован так, как будто это «Кот в шляпе».

Как лучше всего спроектировать схему или написать запрос, чтобы эти записи сортировались по заголовку так же, как библиотеки сортируют заголовок? (Мне также хотелось бы, чтобы я знал технический термин для такого типа упорядочения по названию.) Кроме того, какие соображения производительности следует учитывать и какие индексы я должен создать?

Ответы [ 5 ]

4 голосов
/ 31 марта 2011

Почему бы вам просто не добавить поле "title_prefix" в таблицу и не переместить все эти строки "a" и "a" туда? При оформлении заказа вы должны использовать поле «title», а при представлении заголовка вы можете выполнять конкатенацию любым удобным для вас способом.

3 голосов
/ 31 марта 2011

Создайте пользовательскую функцию (например, sortableTitle?), Которая будет изменять строки, начиная с ваших нежелательных слов.Завершите свой запрос с помощью order by sortableTitle(title).Это потребует дополнительных затрат на ЦП, хотя вам потребуется сравнительный анализ, чтобы узнать, насколько это так.

Вы можете создать дополнительный столбец (sortTitle), который будет заполнен триггером.Это займет некоторое пространство, но тогда ваш сервер сможет сортировать строки по индексу.

За исключением вышесказанного, вы не можете (без изменения кода сервера базы данных) напрямую создать индекс в указанном порядкеты хочешь.Насколько я могу судить, это относится как к MySQL, так и к PostgreSQL.

2 голосов
/ 31 марта 2011

iTunes достигает этого, имея второе поле, в котором заголовок хранится в желаемом формате сортировки и сортируется по нему вместо заголовка.Это звучит как дешевый выход, но когда вы учитываете влияние на производительность выполнения строковых манипуляций с каждым заголовком каждый раз, когда вы делаете оператор select, упорядочивающий по заголовку, против выполнения строковых манипуляций каждый раз, когда вы вставляете или обновляете заголовок, этоимеет смысл.

1 голос
/ 31 марта 2011

Я бы предложил вам разделить поле title на два поля: mainTitle и pre.

Когда заголовок добавлен, проверьте, начинается ли он с "A", "The" или других префиксов, и разбейте его (возможно, с помощью триггера) на два поля. Ваш стол будет выглядеть так:

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

Таким образом, вы можете иметь индекс в поле mainTitle и использовать его для сортировки.

Если вы хотите показать полный заголовок, объедините два поля в любой из двух форм.


  • Если вы выберете этот способ, вам придется соответствующим образом изменить код, когда пользователь дает заголовок для поиска в вашей таблице. Заданный заголовок должен быть разделен таким же образом перед поиском в поле mainTitle.

  • Вы должны быть очень, очень осторожны с кодом (триггером или другим), который выполняет разбиение, чтобы некоторые особые случаи были уловлены правильно. Вы не хотели бы, чтобы книги A = B или A B C: learn the alphabet показывались и сортировались как = B, A и B C: learn the alphabet, A

1 голос
/ 31 марта 2011
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...