Chcę używać tylko pierwszej litery każdego słowa każdego zdania w kolumnie SQL.
Na przykład jeśli zdanie brzmi:
'Lubię filmy'
następnie potrzebuję danych wyjściowych:
'Lubię filmy'
Pytanie:
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]
Tutaj zrobiłem górną, dolną i wielką literę tylko w mojej kolumnie (tutaj wstawiam tylko losowe słowo).
Oto moje wyniki:
Czy są na to jakieś możliwości?
Jakieś możliwości uzyskania wyników bez korzystania z funkcji zdefiniowanej przez użytkownika?
Potrzebuję wyjścia Qwerty Keyboard
sql-server
sql-server-2014
Marin Mohanadas
źródło
źródło
Odpowiedzi:
Najpierw konwertuje ciąg na XML, zastępując wszystkie spacje pustym znacznikiem
<X/>
. Następnie niszczy XML, aby uzyskać jedno słowo w wierszu za pomocąnodes()
. Aby przywrócić wiersze do jednej wartości, wykorzystujefor xml path
lewę.źródło
for xml path
sztuczkę konkatenacji. Chyba że wybierzesz CLR, który byłby najlepszym rozwiązaniem, jeśli ważna jest szybkość i wydajność.W SQL Server 2016 możesz to zrobić za pomocą R, np
To, czy powinieneś, czy nie, to inne pytanie:)
źródło
Być może jestem głupi, ale sprawdzam poniższe zapytanie, które napisałem w stosunku do niektórych z podanych, wydaje się to nieco bardziej wydajne (w zależności od indeksowania).
Kod jest trochę głupi, ale nie ma powiedzenia, że jeśli wygląda głupio, ale działa, to nie jest głupi.
źródło
Inną opcją jest obsługiwanie tego za pośrednictwem SQLCLR. Istnieje nawet metoda dostępna w .NET, która to robi: TextInfo.ToTitleCase (in
System.Globalization
). W tej metodzie pierwsza litera każdego słowa będzie pisana dużymi literami, a pozostałe - małymi literami. W przeciwieństwie do innych propozycji tutaj, pomija także słowa pisane wielkimi literami, zakładając, że są to akronimy. Oczywiście, jeśli takie zachowanie jest pożądane, łatwo byłoby zaktualizować dowolną z sugestii T-SQL, aby to zrobić.Jedną z zalet metody .NET jest to, że może ona zawierać duże litery, które są znakami uzupełniającymi. Na przykład: DESERET SMALL LETTER OW ma mapowanie wielkich liter DESERET CAPITAL LETTER OW (oba pokazują się jako pola po wklejeniu ich tutaj) , ale
UPPER()
funkcja nie zmienia wersji małych liter na duże litery, nawet gdy domyślne sortowanie dla bieżącej bazy danych jest ustawione naLatin1_General_100_CI_AS_SC
. Wydaje się to spójne z dokumentacją MSDN, która nie zawiera tej listy,UPPER
orazLOWER
w zestawieniu funkcji, które zachowują się inaczej podczas korzystania z_SC
Collation: Collation i Unicode: Supplementary Characters .Zwraca (powiększony, aby można było zobaczyć postać dodatkową):
Możesz zobaczyć pełną (i bieżącą) listę znaków pisanych małymi literami i przechodzić na wielkie litery, korzystając z następującej funkcji wyszukiwania na Unicode.org (możesz zobaczyć dodatkowe znaki przewijając w dół, aż dojdziesz do „DESERET” lub po prostu naciśnij Control-Fi wyszukaj to słowo):
http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AChanges_When_Titlecased%3DYes%3A%5D
Chociaż szczerze mówiąc, nie jest to ogromna korzyść, ponieważ wątpliwe jest, aby ktokolwiek faktycznie używał któregokolwiek z Postaci Uzupełniających, które można umieścić w tytułach. Tak czy inaczej, oto kod SQLCLR:
Oto sugestia @ MikaelEriksson - nieznacznie zmodyfikowana, aby obsługiwać
NVARCHAR
dane, a także pomijać słowa pisane wielkimi literami (aby lepiej pasowały do zachowania metody .NET) - wraz z testem tej implementacji T-SQL i implementacja SQLCLR:Inną różnicą w zachowaniu jest to, że ta konkretna implementacja T-SQL dzieli się tylko na spacje, podczas gdy
ToTitleCase()
metoda uważa , że większość liter niebędących literami stanowi separatory słów (stąd różnica w obsłudze części „one & TWO”).Obie implementacje poprawnie obsługują łączenie sekwencji. Każda z akcentowanych liter w „üvÜlA” składa się z litery podstawowej i łączącej diaeresis / umlaut (dwie kropki nad każdą literą) i w obu testach są one poprawnie konwertowane na drugi przypadek.
Wreszcie, jedną nieoczekiwaną wadą wersji SQLCLR jest to, że przy opracowywaniu różnych testów znalazłem błąd w kodzie .NET związany z obsługą listów w kółku (który został teraz zgłoszony w Microsoft Connect - AKTUALIZACJA: Connect został przeniósł się do
/dev/null
- dosłownie - więc może być konieczne ponowne przesłanie tego, jeśli problem nadal występuje). Biblioteka .NET traktuje litery w kółko jako separatory słów, dlatego nie zamienia „ⓐDD” w „Ⓐdd” tak, jak powinno.FYI
Wstępnie wykonana funkcja SQLCLR enkapsulująca
TextInfo.ToTitleCase
powyższą metodę jest teraz dostępna w bezpłatnej wersji SQL # (którą napisałem) jako String_ToTitleCase i String_ToTitleCase4k .😺
źródło
Jako alternatywę dla odpowiedzi Mikaela Erikssona można rozważyć użycie zastrzeżonej obsługi T-SQL ustawiania zmiennych w instrukcjach wyboru w wielu wierszach.
W SQL Server, gdy zmienna jest ustawiana jako część instrukcji SELECT, każdy wiersz wykona iterację logiki zestawu.
Ludzie często używają tej metody do łączenia łańcuchów, choć nie jest ona obsługiwana i istnieją pewne oficjalnie udokumentowane problemy . Oficjalny problem dotyczy określonych cech ORDER BY i nie jest nam potrzebny tutaj, więc być może jest to bezpieczna opcja.
Tutaj iterujemy 26 liter alfabetu i zastępujemy je wielkimi literami, jeśli są poprzedzone spacją. (Początkowo przygotowujemy ciąg znaków, zaczynając od dużej litery od pierwszej litery, a resztę małymi literami, tak jak w pytaniu.)
SQL jest trochę skomplikowany, ponieważ wymaga użycia tabeli liczb - tabeli liczb - do wygenerowania 26 iteracji zastępowania tego, co robi. Możesz utworzyć przydatną wbudowaną funkcję zdefiniowaną przez użytkownika (TVF) do tworzenia tabeli liczb lub możesz nawet użyć tabeli fizycznej.
Wadą tej opcji jest to, że nie może być częścią wbudowanego TVF, ponieważ musi obejmować ustawienie zmiennej. Więc jeśli chcesz zastosować tę metodę do kolumny wyników, musisz zawinąć ją w wielowątkową TVF lub skalarną funkcję zdefiniowaną przez użytkownika.
Jednak jego plan zapytań jest znacznie prostszy i prawdopodobnie znacznie szybszy niż metoda XML. Można argumentować, że jest to również łatwiejsze do zrozumienia (zwłaszcza jeśli masz własny stół do sumowania).
(Przetestowałem to przy użyciu znacznie większego ciągu i było to około 6 ms w porównaniu do 14 ms dla rozwiązania XML).
Z tym rozwiązaniem wiąże się wiele dodatkowych ograniczeń. Jak napisano, zakłada sortowanie bez rozróżniania wielkości liter, chociaż można wyeliminować ten problem, określając sortowanie lub uruchamiając LCASE dla wyszukiwanego hasła, kosztem pewnej wydajności. Zajmuje się także tylko standardowymi literami ASCII i polega na ich umieszczeniu w zestawie znaków , więc nie zrobiłby nic z ñ.
źródło
Zakładając, że szukasz tylko wielkich liter po spacji, oto inny sposób, w jaki możesz to zrobić.
źródło
Może nie być kuloodporny, ale mam nadzieję, że jest to pomocny wkład w ten wątek.
źródło
Poniżej znajduje się procedura, której użyłem w bazie danych Firebird, aby to zrobić. Prawdopodobnie można go dużo posprzątać, ale wykonał za mnie pracę.
źródło
Rekurencyjne CTE są całkiem dobre do tego rodzaju rzeczy.
Prawdopodobnie nie jest szczególnie wydajny w przypadku dużych operacji, ale pozwala na tego rodzaju operacje w instrukcji SQL typu select:
Wynik:
źródło
Podoba mi się ta wersja. Jest prosty i można go użyć do utworzenia funkcji, wystarczy mieć odpowiednią wersję programu SQL Server:
źródło
Mam nadzieję, że pomoże ...
źródło
Dane testowe
Realizacja
źródło