Como contar instâncias de caracteres na coluna SQL


111

Eu tenho uma coluna sql que é uma string de 100 caracteres 'Y' ou 'N'. Por exemplo:

YYNYNYYNNNYYNY ...

Qual é a maneira mais fácil de obter a contagem de todos os símbolos 'Y' em cada linha.


1
Você pode especificar a plataforma? MySQL, MSSQl, Oracle?
Vincent Ramdhanie

Sim - com Oracle, parece que você precisa de comprimento - não len
JGFMK

Respostas:


96

No SQL Server:

SELECT LEN(REPLACE(myColumn, 'N', '')) 
FROM ...

18
Esteja ciente de que se houver mais de "N" ou "Y" na string, isso pode ser impreciso. Veja a solução do nickf para um método mais robusto.
Tom H

319

Este trecho funciona na situação específica onde você tem um booleano: ele responde "quantos não-Ns existem?".

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

Se, em uma situação diferente, você estava realmente tentando contar as ocorrências de um determinado caractere (por exemplo, 'Y') em qualquer string, use isto:

SELECT LEN(col) - LEN(REPLACE(col, 'Y', ''))

32
A segunda é a melhor resposta aqui. Todo o resto depende da situação peculiar da string contendo apenas dois caracteres diferentes.
Steve Bennett

5
Apenas uma observação: no T-SQL, você precisará usar LEN em vez de LENGTH.
Lucas

4
A função len do SQL @nickf corta os espaços finais, então se você estiver procurando por quantas ocorrências de um espaço dentro de uma string, digamos 'Olá', você obterá 0. A maneira mais fácil seria adicionar um caractere final à string antes e ajustar len como tão. SELECIONE LEN (col + '~') - LEN (REPLACE (col, 'Y', '') + '~')
domenicr

3
Se você estiver preocupado com espaços à direita, use a função DATALENGTH.
StevenWhite

2
@StevenWhite DATALENGTH retorna o número de bytes usados. Então o NVARCHAR será duplicado.
domenicr de

18

Isso me deu resultados precisos sempre ...

Isso está no meu campo Stripes ...

Amarelo, Amarelo, Amarelo, Amarelo, Amarelo, Amarelo, Preto, Amarelo, Amarelo, Vermelho, Amarelo, Amarelo, Amarelo, Preto

  • 11 amarelos
  • 2 preto
  • 1 vermelho
SELECT (LEN(Stripes) - LEN(REPLACE(Stripes, 'Red', ''))) / LEN('Red') 
  FROM t_Contacts

Esta é uma maneira muito inteligente! Obrigado
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]

+1 Isso aprimora a segunda sugestão de @nickf para que realmente diga o número de instâncias de uma string, mesmo se a string que você está procurando tiver mais de 1 caractere
Kevin Heidt

A edição de @domenicr quebrou esta resposta e minha edição foi rejeitada. A divisão deve ser por LEN(@StringToFind).
Jamie Kitson

@jamiek desculpas, enviei o código corrigido, mas não sei por que sua edição foi rejeitada.
domenicr de

@domenicr Você deve reverter para o código original, sua edição complica o código inutilmente, @StringToFindnunca será nulo ou vazio.
Jamie Kitson

@JamieKitson vejo o contrário. Verificar se há uma divisão por zero é um princípio das melhores práticas. Além disso, contar o número de espaços em Field To Searchresultaria em uma divisão por zero porque Len(' ')retorna zero.
domenicr

2

Talvez algo assim ...

SELECT
    LEN(REPLACE(ColumnName, 'N', '')) as NumberOfYs
FROM
    SomeTable

1

A maneira mais fácil é usando a função Oracle:

SELECT REGEXP_COUNT(COLUMN_NAME,'CONDITION') FROM TABLE_NAME

1

Isso retornará o número de ocorrências de N

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


0

tente isso

declare @v varchar(250) = 'test.a,1  ;hheuw-20;'
-- LF   ;
select len(replace(@v,';','11'))-len(@v)

0

Experimente isso. Ele determina o não. de ocorrências de um único caractere, bem como as ocorrências de sub-string na string principal.

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);

0

Se você quiser contar o número de instâncias de strings com mais de um único caractere, você pode usar a solução anterior com regex ou esta solução usa STRING_SPLIT, que acredito ter sido introduzido no SQL Server 2016. Além disso, você precisará de compatibilidade nível 130 e superior.

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

0

A segunda resposta fornecida pelo nickf é muito inteligente. No entanto, ele só funciona para um comprimento de caractere da subcadeia de destino de 1 e ignora os espaços. Especificamente, havia dois espaços à esquerda em meus dados, que o SQL remove de forma útil (eu não sabia disso) quando todos os caracteres do lado direito são removidos. O que significava que

"John smith"

gerou 12 usando o método de Nickf, enquanto:

"Joe Bloggs, John Smith"

gerou 10, e

"Joe Bloggs, John Smith, John Smith"

Gerado 20.

Portanto, modifiquei ligeiramente a solução para o seguinte, o que funciona para mim:

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

Tenho certeza que alguém pode pensar em uma maneira melhor de fazer isso!


0

Você também pode tentar isto

-- 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

Resultado:

insira a descrição da imagem aqui


0

A solução abaixo ajuda a descobrir nenhum caractere presente em uma string com uma limitação:

1) usando SELECT LEN (REPLACE (myColumn, 'N', '')), mas limitação e saída errada na condição abaixo:

SELECT LEN (REPLACE ('YYNYNYNNNYYNY', 'N', ''));
--8 --Correto

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

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

2) Experimente a solução abaixo para obter a saída correta:

  • Crie uma função e também modifique de acordo com o requisito.
  • E chame a função conforme abaixo

selecione dbo.vj_count_char_from_string ('123a123a12', '2');
--2 --Correto

selecione dbo.vj_count_char_from_string ('123a123a12', 'a');
--2 --Correto

-- ================================================
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

0

Se você precisa contar o char em uma string com mais de 2 tipos de chars, você pode usar em vez de 'n' -algum operador ou regex dos chars aceitar o char que você precisa.

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

-1

Aqui está o que usei no Oracle SQL para ver se alguém estava passando um número de telefone formatado corretamente:

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

A primeira parte verifica se o número de telefone contém apenas números e o hífen e a segunda parte verifica se o número de telefone contém apenas dois hífens.


O que essa pergunta tem a ver com números de telefone? Ele também está pedindo uma solução T-SQL ...
Ben

-1

por exemplo, para calcular a contagem de instâncias do caractere (a) na coluna SQL -> nome é o nome da coluna '' (e em doblequote está vazio, substituo a por nocharecter @ '')

selecione len (nome) - len (substituir (nome, 'a', '')) em TESTE

selecione len ('YYNYNYYNNNYYNY') - len (substituir ('YYNYNYYNNNYYNY', 'y', ''))

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.