Как я могу отсортировать SQLite-запрос, игнорируя статьи ( "the", "a" и т.д.)?
Я использую С# для отображения списка названий фильмов, которые я вызываю из базы данных SQLite. В настоящее время я использую собственный класс ListBox, который имеет функцию для сортировки текста, разделяющего слово "The" с начала каждого элемента. Однако это не совсем простой способ сделать это, поскольку он вызывает базу данных SQLite и затем сортирует. Я бы предпочел сократить его до одного шага, надеюсь, что он будет сортироваться прямо из базы данных в моем запросе "SELECT".
Я сделал несколько поисков по этому вопросу и нашел некоторые предложения, в том числе создание дополнительного столбца сортировки в базе данных. Хотя это, безусловно, возможность, мне интересно, есть ли более простые варианты, которые не требуют вставки почти идентичной повторяющейся информации (особенно, если база данных становится больше). Я новичок в SQLite, но я кое-что прочитал о создании функции сортировки, которая может использоваться для создания пользовательского заказа. Тем не менее, я не уверен, подходит ли это для этого и не может найти никакой помощи в его реализации на С#.
Было надеяться, что кто-то сможет поделиться некоторыми рекомендациями. Если дополнительный столбец сортировки - лучший способ, то это то, что я буду делать.
Ответы
Ответ 1
Чтобы не вставлять повторяющиеся данные, о наличии двух столбцов: TITLE_PREFIX (обычно пустой, но иногда содержит "The" или "A", индекс не указан в этом столбце) и TITLE (содержит название без "The" или "A", это столбец, в который вы создаете индекс). Чтобы отобразить данные, вам необходимо объединить TITLE_PREFIX и TITLE. Но вы просто ищете TITLE.
Ответ 2
Вот решение:
ORDER BY (CASE
WHEN sortTitle LIKE 'the %' THEN substr(sortTitle,5)
WHEN sortTitle LIKE 'a %' THEN substr(sortTitle,3)
WHEN sortTitle LIKE 'an %' THEN substr(sortTitle,4)
ELSE sortTitle END)
Ответ 3
Вы можете сохранить каждый заголовок в двух частях: title
и prefix
.
С SQLite вы можете объединить 2 строковых значения через || operator
, также известный как concatenate operator
.
Вот пример:
SELECT prefix || ' ' || title FROM movies ORDER BY title
Вы также можете использовать ltrim
, если префикс пуст, поэтому у вас нет места спереди:
SELECT ltrim(prefix || ' ' || title) FROM movies ORDER BY title
Другой альтернативой является сохранение префикса в конце заголовка. Например, во многих магазинах фильмов вы увидите что-то вроде:
Три мушкетера, The
Ответ 4
Внутри кода С#
Если вы хотите сделать это в С#, используйте LINQ, чтобы сделать заказ для вас. Я опубликовал полный образец в PasteBin. Это позволит вам:
- избегать дублирования данных в вашей базе данных
- используйте индексы DB, как обычно, независимо от того, какие RDBMS
- помещать шумовые слова в файл конфигурации, тем самым уменьшая время простоя/перестраивая/передислоцируя при изменении списка
- убедитесь, что решение более читаемо в коде клиента
DropDownList1.DataSource = myBooks.OrderBy(n => ReplaceNoise(n.Title))
public string ReplaceNoise(string input)
{
string[] noise = new string[] { "the", "an", "a" };
//surely this could be LINQ'd
foreach (string n in noise)
{
if (input.ToLower().StartsWith(n))
{
return input.Substring(n.Length).Trim();
}
}
return input;
}
В вашем заявлении SQLite
Как просто заменить шумовые слова пробелами в порядке? Это уродливый первый шаг, но решительно рассмотрите новый столбец для хранения этого значения для целей сортировки.
ORDER BY REPLACE(REPLACE([title],'the',''), 'a', '')
По общему признанию, это становится уродливым, когда вы закончите с этим:
REPLACE(REPLACE(REPLACE(REPLACE([title],'The ',''),'a',''),'of',''),'by','')
Ответ 5
Вы можете создать таблицу, поддерживающую полнотекстовый поиск (используя FTS модуль) в заголовке. Затем вы сможете быстро выполнять поиск по любым словам в названии, не требуя при этом дополнительной дополнительной работы с вашей стороны. Например, пользовательский запрос good bad ugly может создать "Хорошее, плохое и угрюмое" как один из его первых результатов. Дополнительная стоимость всего этого составляет около четверти длины самого текста в целом, но может быть больше для вашего набора данных, поскольку заголовки не являются полным текстом на английском языке. Вам также нужно потратить время на создание дополнительных индексов - вы не хотите создавать их на своем основном наборе данных в живой системе (очевидно), но это не должно быть слишком большой проблемой.
Ответ 6
Создайте виртуальный столбец (результат функции, который может быть реализован на С#) и выполните сортировку по этому виртуальному столбцу. Функция может перемещать "The" до конца, как в "Three Musketeers, The", или отбрасывать "The", что бы вы ни хотели сделать.