Czy istnieje prosty sposób na znalezienie indeksu ostatniego wystąpienia łańcucha za pomocą SQL? Obecnie używam SQL Server 2000. Zasadniczo potrzebuję funkcjonalności, którą zapewnia .NETSystem.String.LastIndexOf
zapewnia metoda . Trochę googlowanie ujawniło to - Funkcja pobierania ostatniego indeksu - ale to nie zadziała, jeśli przekażesz wyrażenie kolumnowe „tekst”. Inne rozwiązania znalezione gdzie indziej działają tylko wtedy, gdy wyszukiwany tekst ma długość 1 znaku.
Prawdopodobnie będę musiał ugotować funkcję. Jeśli to zrobię, opublikuję go tutaj, abyście mogli go obejrzeć i być może z niego skorzystać.
DATALENGTH
zwraca liczbę bajtów, a nie znaków. DlategoDATALENGTH
zwraca 2 x liczbę znaków w ciągu dlaNVARCHAR
ciągów.LEN
jednak zwraca liczbę znaków minus wszelkie końcowe białe znaki . Nigdy nie używaćDATALENGTH
do obliczania długości postać chyba końcowe spacje są istotne i wiem na pewno, że moje typy danych są spójne, czy sąVARCHAR
lubNVARCHAR
Prosty sposób? Nie, ale użyłem odwrotności. Dosłownie.
We wcześniejszych procedurach, aby znaleźć ostatnie wystąpienie danego ciągu, użyłem funkcji REVERSE (), a następnie CHARINDEX, a następnie ponownie REVERSE, aby przywrócić pierwotną kolejność. Na przykład:
pokazuje, jak wyodrębnić rzeczywiste nazwy plików bazy danych z ich „nazw fizycznych”, bez względu na to, jak głęboko są one zagnieżdżone w podfolderach. To wyszukuje tylko jeden znak (ukośnik odwrotny), ale możesz na tej podstawie zbudować dłuższe ciągi wyszukiwania.
Jedynym minusem jest to, że nie wiem, jak dobrze to zadziała na typach danych TEXT. Korzystam z SQL 2005 od kilku lat i nie jestem już zaznajomiony z pracą z TEKSTEM - ale wydaje mi się, że mógłbyś użyć na nim LEWEGO i PRAWEGO?
Philip
źródło
Najprostszy sposób to ...
źródło
[expr]
symbol jest dłuższy niż 1, również musisz go odwrócić!Jeśli używasz Sqlserver 2005 lub nowszego,
REVERSE
wielokrotne używanie funkcji jest szkodliwe dla wydajności, poniższy kod jest bardziej wydajny.źródło
źródło
Stare, ale wciąż aktualne pytanie, więc oto, co stworzyłem na podstawie informacji dostarczonych przez innych tutaj.
źródło
To działało bardzo dobrze dla mnie.
źródło
działało lepiej dla mnie
źródło
Hmm, wiem, że to stary wątek, ale tabela podsumowująca mogłaby to zrobić w SQL2000 (lub dowolnej innej bazie danych):
Tabela podsumowująca to tylko tabela liczb rosnących.
Plik
substring(@str, _Tally.n, 1) = @delim
Dostaje położenie każdego separatora, a następnie po prostu uzyskać maksymalną pozycję w tym zestawie.Tally Tally są niesamowite. Jeśli nie korzystałeś z nich wcześniej, jest dobry artykuł na temat SQL Server Central (bezpłatna rejestracja lub po prostu użyj Bug Me Not ( http://www.bugmenot.com/view/sqlservercentral.com )).
* EDYCJA: Usunięto
n <= LEN(TEXT_FIELD)
, ponieważ nie można użyć LEN () na typie TEKST. Dopókisubstring(...) = @delim
pozostaje, choć wynik jest nadal prawidłowy.źródło
Odwróć zarówno ciąg, jak i podciąg, a następnie wyszukaj pierwsze wystąpienie.
źródło
Niektóre inne odpowiedzi zwracają rzeczywisty ciąg, podczas gdy ja musiałem znać rzeczywisty indeks int. A odpowiedzi, które to robią, wydają się nadmiernie komplikować sprawę. Korzystając z innych odpowiedzi jako inspiracji, zrobiłem następujące ...
Najpierw utworzyłem funkcję:
Następnie w swoim zapytaniu możesz po prostu zrobić to:
Powyższe powinno zwrócić 23 (ostatni indeks „:”)
Mam nadzieję, że komuś to trochę ułatwiło!
źródło
Zdaję sobie sprawę, że to pytanie sprzed kilku lat, ale ...
On
Access 2010
, można użyćInStrRev()
do tego celu. Mam nadzieję że to pomoże.źródło
Ta odpowiedź używa MS SQL Server 2008 (nie mam dostępu do MS SQL Server 2000), ale widzę to według OP to 3 sytuacje, które należy wziąć pod uwagę. Z tego, czego próbowałem, żadna odpowiedź nie obejmuje wszystkich 3 z nich:
0
Funkcja, którą wymyśliłem, przyjmuje 2 parametry:
@String NVARCHAR(MAX)
: Ciąg do wyszukiwania@FindString NVARCHAR(MAX)
: Pojedynczy znak lub podłańcuch do pobrania ostatniego indeksu w@String
Zwraca wartość będącą
INT
dodatnim indeksem@FindString
w@String
lub0
znaczeniem, którego@FindString
nie ma@String
Oto wyjaśnienie, co robi ta funkcja:
@ReturnVal
aby0
wskazać, że@FindString
nie ma tego w programie@String
@FindString
w@String
przy użyciuCHARINDEX()
@FindString
w@String
to0
,@ReturnVal
jest pozostawiony jako0
@FindString
w@String
jest> 0
,@FindString
jest w,@String
więc oblicza ostatni indeks@FindString
w@String
przy użyciuREVERSE()
@ReturnVal
liczbę dodatnią będącą ostatnim indeksem@FindString
w@String
lub0
wskazującą, że@FindString
nie ma tego elementu@String
Oto skrypt funkcji tworzenia (gotowy do kopiowania i wklejania):
Oto fragment, który wygodnie testuje funkcję:
Uruchomiłem to tylko na MS SQL Server 2008, ponieważ nie mam dostępu do żadnej innej wersji, ale z tego, co sprawdziłem, powinno to być dobre przynajmniej dla 2008+.
Cieszyć się.
źródło
Wiem, że będzie to nieefektywne, ale czy zastanawiałeś się nad rzutowaniem
text
pola navarchar
to, abyś mógł skorzystać z rozwiązania dostarczonego przez znalezioną stronę internetową? Wiem, że to rozwiązanie stworzyłoby problemy, ponieważ możesz potencjalnie skrócić rekord, jeśli długość wtext
polu przekroczyłaby długość twojegovarchar
(nie wspominając o tym, że nie byłby zbyt wydajny).Ponieważ dane znajdują się wewnątrz
text
pola (i używasz programu SQL Server 2000), opcje są ograniczone.źródło
Jeśli chcesz uzyskać indeks ostatniej spacji w ciągu słów, możesz użyć tego wyrażenia RIGHT (nazwa, (CHARINDEX ('', REVERSE (nazwa), 0)), aby zwrócić ostatnie słowo w ciągu. jest przydatne, jeśli chcesz przeanalizować nazwisko pełnego imienia, które zawiera inicjały pierwszego i / lub drugiego imienia.
źródło
@indexOf = <whatever characters you are searching for in your string>
@LastIndexOf = LEN([MyField]) - CHARINDEX(@indexOf, REVERSE([MyField]))
Nie testowane, może być wyłączone o jeden z powodu zerowego indeksu, ale działa w
SUBSTRING
funkcji podczas odcinania od@indexOf
znaków do końca ciąguSUBSTRING([MyField], 0, @LastIndexOf)
źródło
Ten kod działa nawet wtedy, gdy podciąg zawiera więcej niż 1 znak.
źródło
Musiałem znaleźć n-tą ostatnią pozycję ukośnika odwrotnego w ścieżce folderu. Oto moje rozwiązanie.
Oto moje przypadki testowe, które pomyślnie przeszły
źródło
Aby uzyskać część przed ostatnim wystąpieniem ogranicznika (działa tylko ze
NVARCHAR
względu naDATALENGTH
użycie):źródło
Ta odpowiedź spełnia wymagania PO. w szczególności pozwala na to, aby igła miała więcej niż jeden znak i nie generuje błędu, gdy igła nie zostanie znaleziona w stogu siana. Wydawało mi się, że większość (wszystkie?) Z pozostałych odpowiedzi nie dotyczyła tych skrajnych przypadków. Poza tym dodałem argument "Pozycja początkowa" dostarczany przez natywną funkcję CharIndex serwera MS SQL. Próbowałem dokładnie odzwierciedlić specyfikację CharIndex, z wyjątkiem przetwarzania od prawej do lewej zamiast od lewej do prawej. np. zwracam wartość null, jeśli igła lub stóg siana jest zerowa, a zwracam zero, jeśli igła nie została znaleziona w stogu siana. Jedną rzeczą, której nie mogłem obejść, jest to, że przy wbudowanej funkcji trzeci parametr jest opcjonalny. W przypadku funkcji zdefiniowanych przez użytkownika programu SQL Server wszystkie parametry muszą zostać podane w wywołaniu, chyba że funkcja jest wywoływana przy użyciu polecenia „EXEC” . Podczas gdy trzeci parametr musi znajdować się na liście parametrów, możesz podać słowo kluczowe „default” jako symbol zastępczy dla niego bez konieczności nadawania mu wartości (patrz przykłady poniżej). Ponieważ łatwiej jest usunąć trzeci parametr z tej funkcji, jeśli nie jest to pożądane, niż dodanie go w razie potrzeby, umieściłem go tutaj jako punkt wyjścia.
źródło
Natknąłem się na ten wątek, szukając rozwiązania mojego podobnego problemu, które miało dokładnie takie same wymagania, ale dotyczyło innego rodzaju bazy danych, która również nie zawierała
REVERSE
funkcji.W moim przypadku był to plik bazy danych OpenEdge (Progress) , która ma nieco inną składnię. Dzięki temu
INSTR
udostępniono mi funkcję, którą oferuje większość baz danych typu Oracle .Więc wymyśliłem następujący kod:
Jednak w mojej konkretnej sytuacji (będącej OpenEdge (Progress) danych ) nie spowodowało to pożądanego zachowania, ponieważ zastąpienie znaku pustym znakiem dało taką samą długość jak oryginalny ciąg. Nie ma to dla mnie większego sensu, ale udało mi się ominąć problem z poniższym kodem:
Teraz rozumiem, że ten kod nie rozwiąże problemu T-SQL ponieważ nie ma alternatywy dla
INSTR
funkcji, która oferujeOccurence
właściwość.Dla dokładności dodam kod potrzebny do utworzenia tej funkcji skalarnej, aby można było jej używać w taki sam sposób, jak w powyższych przykładach.
Aby uniknąć oczywistego, gdy
REVERSE
funkcja jest dostępna, nie musisz tworzyć tej funkcji skalarnej i możesz po prostu uzyskać wymagany wynik w następujący sposób:źródło