Jak liczyć wystąpienia znaku w kolumnie SQL

111

Mam kolumnę sql, która jest ciągiem 100 znaków „Y” lub „N”. Na przykład:

YYNYNYYNNNYYNY ...

Jaki jest najłatwiejszy sposób, aby uzyskać liczbę wszystkich symboli „Y” w każdym wierszu.

cindi
źródło
1
Czy możesz określić platformę? MySQL, MSSQl, Oracle?
Vincent Ramdhanie
Tak - w przypadku Oracle wydaje się, że potrzebujesz długości - nie len
JGFMK

Odpowiedzi:

96

W SQL Server:

SELECT LEN(REPLACE(myColumn, 'N', '')) 
FROM ...
David Hedlund
źródło
18
Pamiętaj tylko, że jeśli w ciągu znaków jest więcej niż „N” lub „Y”, może to być niedokładne. Zobacz rozwiązanie nickf, aby uzyskać bardziej niezawodną metodę.
Tom H
319

Ten fragment kodu działa w konkretnej sytuacji, w której masz wartość logiczną: odpowiada „ile jest elementów innych niż N?”.

SELECT LEN(REPLACE(col, 'N', ''))

Jeśli w innej sytuacji faktycznie próbowałeś policzyć wystąpienia określonego znaku (na przykład `` Y '') w dowolnym podanym ciągu, użyj tego:

SELECT LEN(col) - LEN(REPLACE(col, 'Y', ''))
nickf
źródło
32
Druga to najlepsza odpowiedź. Cała reszta polega na szczególnej sytuacji ciągu zawierającego tylko dwa różne znaki.
Steve Bennett
5
Tylko uwaga: w T-SQL musisz użyć LEN zamiast LENGTH.
Łukasz
4
@nickf Funkcja SQL len przycina końcowe spacje, więc jeśli szukasz liczby wystąpień spacji w ciągu, powiedzmy „Cześć”, otrzymasz 0. Najłatwiejszym sposobem byłoby dodanie końcowego znaku do ciągu przed i dostosowanie długości do więc. SELECT LEN (col + '~') - LEN (REPLACE (col, 'Y', '') + '~')
domenicr
3
Jeśli obawiasz się spacji końcowych, zamiast tego użyj funkcji DATALENGTH.
StevenWhite
2
@StevenWhite DATALENGTH zwraca liczbę użytych bajtów. Więc NVARCHAR zostanie podwojony.
domenicr
18

To dawało mi dokładne wyniki za każdym razem ...

To jest w moim polu Stripes ...

Żółty, żółty, żółty, żółty, żółty, żółty, czarny, żółty, żółty, czerwony, żółty, żółty, żółty, czarny

  • 11 żółtych
  • 2 czarny
  • 1 czerwony
SELECT (LEN(Stripes) - LEN(REPLACE(Stripes, 'Red', ''))) / LEN('Red') 
  FROM t_Contacts
Ron Sell
źródło
To bardzo sprytny sposób! Dziękuję
Thelt
13
DECLARE @StringToFind VARCHAR(100) = "Text To Count"

SELECT (LEN([Field To Search]) - LEN(REPLACE([Field To Search],@StringToFind,'')))/COALESCE(NULLIF(LEN(@StringToFind), 0), 1) --protect division from zero
FROM [Table To Search]
Aaron Dake
źródło
+1 To wzmacnia drugą sugestię @nickf, dzięki czemu będzie faktycznie wskazywać liczbę wystąpień ciągu, nawet jeśli szukany ciąg ma więcej niż 1 znak
Kevin Heidt
Edycja @ domenicr zepsuła tę odpowiedź i moja zmiana została odrzucona. Podział powinien nastąpić LEN(@StringToFind).
Jamie Kitson
@jamiek przeprosiny Przesłałem poprawiony kod, ale nie wiem, dlaczego Twoja zmiana została odrzucona.
domenicr
@domenicr Powinieneś powrócić do oryginalnego kodu, twoja edycja komplikuje kod bez celu, @StringToFindnigdy nie będzie pusta lub pusta.
Jamie Kitson
@JamieKitson Widzę inaczej. Sprawdzanie dzielenia przez zero jest zasadą najlepszych praktyk. Ponadto zliczenie liczby spacji Field To Searchdałoby dzielenie przez zero, ponieważ Len(' ')zwraca zero.
domenicr
2

Może coś takiego ...

SELECT
    LEN(REPLACE(ColumnName, 'N', '')) as NumberOfYs
FROM
    SomeTable
Jason Punyon
źródło
1

Najprościej jest skorzystać z funkcji Oracle:

SELECT REGEXP_COUNT(COLUMN_NAME,'CONDITION') FROM TABLE_NAME
Mayuresh Bhabal
źródło
1

Zwróci liczbę wystąpień N

select ColumnName, LEN(ColumnName)- LEN(REPLACE(ColumnName, 'N', '')) from Table

Faisal Shahzad
źródło
0

Spróbuj tego

declare @v varchar(250) = 'test.a,1  ;hheuw-20;'
-- LF   ;
select len(replace(@v,';','11'))-len(@v)
user5546076
źródło
0

Spróbuj tego. Określa nie. wystąpień pojedynczych znaków, a także wystąpień podłańcucha w ciągu głównym.

SELECT COUNT(DECODE(SUBSTR(UPPER(:main_string),rownum,LENGTH(:search_char)),UPPER(:search_char),1)) search_char_count
FROM DUAL
connect by rownum <= length(:main_string);
Himanshu Tiwari
źródło
0

Jeśli chcesz policzyć liczbę wystąpień ciągów zawierających więcej niż jeden znak, możesz użyć poprzedniego rozwiązania z wyrażeniem regularnym lub to rozwiązanie używa STRING_SPLIT, które, jak sądzę, zostało wprowadzone w SQL Server 2016. Będziesz także potrzebować zgodności poziom 130 i wyższy.

ALTER DATABASE [database_name] SET COMPATIBILITY_LEVEL = 130

.

--some data
DECLARE @table TABLE (col varchar(500))
INSERT INTO @table SELECT 'whaCHAR(10)teverCHAR(10)whateverCHAR(10)'
INSERT INTO @table SELECT 'whaCHAR(10)teverwhateverCHAR(10)'
INSERT INTO @table SELECT 'whaCHAR(10)teverCHAR(10)whateverCHAR(10)~'

--string to find
DECLARE @string varchar(100) = 'CHAR(10)'

--select
SELECT 
    col
  , (SELECT COUNT(*) - 1 FROM STRING_SPLIT (REPLACE(REPLACE(col, '~', ''), 'CHAR(10)', '~'), '~')) AS 'NumberOfBreaks'
FROM @table
user3469285
źródło
0

Druga odpowiedź udzielona przez nickf jest bardzo sprytna. Jednak działa tylko dla długości znaku docelowego podłańcucha równej 1 i ignoruje spacje. W szczególności w moich danych były dwie wiodące spacje, które SQL z łatwością usuwa (nie wiedziałem o tym), gdy wszystkie znaki po prawej stronie zostaną usunięte. Co to znaczyło

" John Smith"

wygenerował 12 metodą Nickfa, natomiast:

„Joe Bloggs, John Smith”

wygenerowano 10 i

„Joe Bloggs, John Smith, John Smith”

Wygenerowano 20.

Dlatego nieznacznie zmodyfikowałem rozwiązanie do następującego, które działa dla mnie:

Select (len(replace(Sales_Reps,' ',''))- len(replace((replace(Sales_Reps, ' ','')),'JohnSmith','')))/9 as Count_JS

Jestem pewien, że ktoś może wymyślić lepszy sposób na zrobienie tego!

Statsanalyst
źródło
0

Możesz także spróbować tego

-- DECLARE field because your table type may be text
DECLARE @mmRxClaim nvarchar(MAX) 

-- Getting Value from table
SELECT top (1) @mmRxClaim = mRxClaim FROM RxClaim WHERE rxclaimid_PK =362

-- Main String Value
SELECT @mmRxClaim AS MainStringValue

-- Count Multiple Character for this number of space will be number of character
SELECT LEN(@mmRxClaim) - LEN(REPLACE(@mmRxClaim, 'GS', ' ')) AS CountMultipleCharacter

-- Count Single Character for this number of space will be one
SELECT LEN(@mmRxClaim) - LEN(REPLACE(@mmRxClaim, 'G', '')) AS CountSingleCharacter

Wynik:

wprowadź opis obrazu tutaj

atik sarker
źródło
0

Poniższe rozwiązanie pomaga znaleźć brak znaku występującego w ciągu z ograniczeniem:

1) za pomocą SELECT LEN (REPLACE (myColumn, 'N', '')), ale ograniczenie i nieprawidłowe wyjście w poniższym stanie:

SELECT LEN (REPLACE ('YYNYNYYNNNYYNY', 'N', ''));
--8 - Prawidłowo

SELECT LEN (REPLACE ('123a123a12', 'a', ''));
--8 - Źle

SELECT LEN (REPLACE ('123a123a12'; '1', ''));
--7 - Źle

2) Wypróbuj poniższe rozwiązanie, aby uzyskać poprawne wyniki:

  • Utwórz funkcję, a także zmodyfikuj zgodnie z wymaganiami.
  • I zadzwoń do funkcji jak poniżej

select dbo.vj_count_char_from_string ('123a123a12', '2');
--2 - Prawidłowo

select dbo.vj_count_char_from_string ('123a123a12', 'a');
--2 - Prawidłowo

-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      VIKRAM JAIN
-- Create date: 20 MARCH 2019
-- Description: Count char from string
-- =============================================
create FUNCTION vj_count_char_from_string
(
    @string nvarchar(500),
    @find_char char(1)  
)
RETURNS integer
AS
BEGIN
    -- Declare the return variable here
    DECLARE @total_char int; DECLARE @position INT;
    SET @total_char=0; set @position = 1;

    -- Add the T-SQL statements to compute the return value here
    if LEN(@string)>0
    BEGIN
        WHILE @position <= LEN(@string) -1
        BEGIN
            if SUBSTRING(@string, @position, 1) = @find_char
            BEGIN
                SET @total_char+= 1;
            END
            SET @position+= 1;
        END
    END;

    -- Return the result of the function
    RETURN @total_char;

END
GO
jainvikram444
źródło
0

Jeśli chcesz policzyć znak w łańcuchu z więcej niż 2 rodzajami znaków, możesz użyć zamiast 'n' -jakiegoś operatora lub wyrażenia regularnego znaków, zaakceptuj potrzebny znak.

SELECT LEN(REPLACE(col, 'N', ''))
Saurabh Bhandari
źródło
-1

Oto, czego użyłem w Oracle SQL, aby sprawdzić, czy ktoś przekazuje poprawnie sformatowany numer telefonu:

WHERE REPLACE(TRANSLATE('555-555-1212','0123456789-','00000000000'),'0','') IS NULL AND
LENGTH(REPLACE(TRANSLATE('555-555-1212','0123456789','0000000000'),'0','')) = 2

Pierwsza część sprawdza, czy numer telefonu zawiera tylko cyfry i łącznik, a druga część sprawdza, czy numer telefonu ma tylko dwa łączniki.

TonyK
źródło
Co to pytanie ma wspólnego z numerami telefonów? Prosi również o rozwiązanie T-SQL ...
Ben,
-1

na przykład, aby obliczyć liczbę wystąpień znaku (a) w kolumnie SQL -> nazwa to nazwa kolumny '' (a w doblequote jest puste, zastępuję a z nocharecter @ '')

wybierz len (name) - len (replace (name, 'a', '')) z TESTING

select len ​​('YYNYNYYNNNYYNY') - len (zamień ('YYNYNYYNNNYYNY', 'y', ''))

gady RajinikanthB
źródło