Я хочу использовать только первую букву каждого слова каждого предложения в столбце SQL.
Например, если предложение:
'Мне нравятся фильмы'
тогда мне нужен вывод:
'Мне нравятся фильмы'
Запрос:
declare @a varchar(15)
set @a = 'qWeRtY kEyBoArD'
select @a as [Normal text],
upper(@a) as [Uppercase text],
lower(@a) as [Lowercase text],
upper(left(@a,1)) + lower(substring(@a,2,len(@a))) as [Capitalize first letter only]
Здесь я сделал верхнюю, нижнюю и заглавную первую букву только в своем столбце (здесь я поместил только случайное слово).
Вот мои результаты:
Есть ли возможность сделать это?
Есть ли возможность получить результаты без использования определенной пользователем функции?
Мне нужен выход Qwerty Keyboard
sql-server
sql-server-2014
Марин Моханадас
источник
источник
Ответы:
Сначала он преобразует строку в XML, заменяя все пробелы пустым тегом
<X/>
. Затем он уничтожает XML, чтобы получить по одному слову в строкеnodes()
. Чтобы вернуть строки к одному значению, он используетfor xml path
хитрость.источник
for xml path
уловки для объединения. Если вы не выберете CLR, который будет лучшим вариантом, если важны скорость и эффективность.В SQL Server 2016 вы можете сделать это с помощью R, например
Должен ты или нет - это другой вопрос :)
источник
Может быть, я идиот, но, проверяя приведенный ниже запрос с некоторыми из представленных, это кажется немного более эффективным (в зависимости от индексации).
Код немного глупый, но разве не говорят, что если он выглядит глупо, но работает, то он не глупый.
источник
Другой вариант - обработать это через SQLCLR. В .NET уже есть метод, который делает это: TextInfo.ToTitleCase (in
System.Globalization
). Этот метод будет в верхнем регистре первой буквы каждого слова, а в нижнем регистре остальные буквы. В отличие от других предложений, здесь также пропускаются слова в верхнем регистре, считая их аббревиатурами. Конечно, если это необходимо, было бы достаточно просто обновить любое из предложений T-SQL, чтобы сделать это.Одним из преимуществ метода .NET является то, что он может использовать буквы верхнего регистра, которые являются дополнительными символами. Например: DESERET SMALL LETTER OW имеет отображение в верхнем регистре DESERET CAPITAL LETTER OW (оба отображаются в виде блоков, когда я вставляю их сюда) , но
UPPER()
функция не изменяет версию нижнего регистра на верхний регистр, даже когда Сортировка по умолчанию для текущей базы данных установлена наLatin1_General_100_CI_AS_SC
. Кажется, это согласуется с документацией MSDN, в которой нет перечняUPPER
иLOWER
в таблице функций, которые ведут себя по-разному при использовании параметров_SC
Collation: Collation и Unicode: Дополнительные символы .Возвращает (увеличено, чтобы вы могли видеть дополнительный символ):
Вы можете увидеть полный (и текущий) список символов в нижнем регистре и изменить его в верхний регистр, используя следующую функцию поиска на Unicode.org (вы можете увидеть дополнительные символы, прокручивая вниз, пока не дойдете до «DESERET») раздел, или просто нажмите Control-Fи найдите это слово):
http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AChanges_When_Titlecased%3DYes%3A%5D
Хотя, честно говоря, это не является огромным преимуществом, так как сомнительно, что кто-то на самом деле использует какой-либо из дополнительных символов, которые могут быть в названии. В любом случае, вот код SQLCLR:
Вот предложение @ MikaelEriksson - слегка измененное для обработки
NVARCHAR
данных, а также для пропуска слов в верхнем регистре (чтобы более точно соответствовать поведению метода .NET) - вместе с тестом этой реализации T-SQL и реализация SQLCLR:Другое различие в поведении состоит в том, что эта конкретная реализация T-SQL разделяется только на пробелы, тогда как
ToTitleCase()
метод рассматривает большинство не-букв как разделители слов (отсюда и разница в обработке части «one & TWO»).Обе реализации правильно обрабатывают комбинируемые последовательности. Каждая из акцентированных букв в «üvÜlA» состоит из базовой буквы и сочетания диареза / умляута (две точки над каждой буквой), и они правильно преобразуются в другой случай в обоих тестах.
Наконец, один неожиданный недостаток версии SQLCLR заключается в том, что при создании различных тестов я обнаружил ошибку в коде .NET, связанную с обработкой кружковых букв (о которой теперь сообщалось в Microsoft Connect - UPDATE: Connect был переехал
/dev/null
- буквально - так что мне может понадобиться повторить это, если проблема все еще существует). Библиотека .NET рассматривает Обведенные буквы как разделители слов, поэтому она не превращает «ⓐDD» в «Ⓐdd», как следует.FYI
Готовая функция SQLCLR, инкапсулирующая
TextInfo.ToTitleCase
упомянутый выше метод, теперь доступна в бесплатной версии SQL # (которую я написал) как String_ToTitleCase и String_ToTitleCase4k .😺
источник
В качестве альтернативы ответу Микаэля Эрикссона вы можете рассмотреть возможность использования проприетарной обработки переменных в T-SQL в операторах выбора нескольких строк.
В SQL Server, когда переменная устанавливается как часть инструкции SELECT, каждая строка будет выполнять итерацию заданной логики.
Люди часто используют этот метод для объединения строк, хотя он не поддерживается и есть некоторые официально задокументированные проблемы с ним . Официальная проблема связана с конкретными характеристиками ORDER BY, и нам здесь это не нужно, поэтому, возможно, это безопасный вариант.
Здесь мы перебираем 26 букв алфавита и заменяем их заглавной версией, если им предшествует пробел. (Первоначально мы подготавливаем строку, используя заглавные буквы и оставляя строчные буквы, как вы сделали в своем вопросе.)
SQL немного сложен, потому что требует использования таблицы подсчета - таблицы чисел - для генерации 26 итераций замены, которую он выполняет. Вы можете создать удобную встроенную определяемую пользователем табличную функцию (TVF) для создания этой таблицы чисел или даже использовать физическую таблицу.
Недостаток этой опции заключается в том, что она не может быть частью встроенного TVF, поскольку для этого необходимо установить переменную. Поэтому, если вы хотите применить этот метод к столбцу выходных данных, вам нужно будет обернуть его в TVF с несколькими операторами или скалярную пользовательскую функцию.
Тем не менее, его план запросов намного проще и, вероятно, значительно быстрее, чем метод XML. Вы могли бы поспорить, что это также легче понять (особенно, если у вас есть собственный подсчет).
(Я проверил это, используя намного большую строку, и для решения XML это было около 6 мс против 14 мс.)
У этого решения есть ряд дополнительных ограничений. Как написано, он предполагает сортировку без учета регистра, хотя эту проблему можно устранить, указав параметры сортировки или запустив LCASE в поисковом запросе, за счет некоторой производительности. Он также обращается только к стандартным буквам ASCII и полагается на их размещение в наборе символов , поэтому он не будет иметь ничего общего с ñ.
источник
Предполагая, что вы ищете только заглавные слова после пробела, вот еще один способ сделать это.
источник
Не может быть пуленепробиваемым, но я надеюсь, что это полезный вклад в эту тему.
источник
Ниже описана процедура, которую я использовал в базе данных Firebird для этого. Вероятно, можно много чего почистить, но это сделало работу за меня.
источник
Рекурсивные CTE довольно хороши для такого рода вещей.
Вероятно, не особенно эффективен для больших операций, но допускает такую операцию в чистом SQL-выражении select:
Выход:
источник
Мне нравится эта версия. Это просто и может быть использовано для создания функции, вам просто нужно иметь правильную версию SQL Server:
источник
Я надеюсь, что поможет ...
источник
Тестовые данные
Реализация
источник