Cómo contar instancias de carácter en la columna SQL


111

Tengo una columna sql que es una cadena de 100 caracteres 'Y' o 'N'. Por ejemplo:

YYNYNYYNNNYYNY ...

¿Cuál es la forma más fácil de obtener el recuento de todos los símbolos 'Y' en cada fila?


1
¿Puede especificar la plataforma? ¿MySQL, MSSQl, Oracle?
Vincent Ramdhanie

Sí, con Oracle parece que necesita longitud, no longitud
JGFMK

Respuestas:


96

En SQL Server:

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

18
Solo tenga en cuenta que si hay más de "N" o "Y" en la cadena, esto podría ser inexacto. Consulte la solución de nickf para obtener un método más sólido.
Tom H

319

Este fragmento funciona en la situación específica en la que tiene un booleano: responde "¿cuántos no N hay?".

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

Si, en una situación diferente, en realidad estaba tratando de contar las apariciones de un determinado carácter (por ejemplo, 'Y') en una cadena determinada, use esto:

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

32
La segunda es la mejor respuesta aquí. Todos los demás dependen de la situación peculiar de la cadena que contiene solo dos caracteres diferentes.
Steve Bennett

5
Solo una nota: en T-SQL, deberá usar LEN en lugar de LENGTH.
Lucas

4
La función @nickf SQL len recorta los espacios finales, por lo que si estuviera buscando cuántas ocurrencias de un espacio dentro de una cadena, digamos 'Hola', obtendría 0. La forma más fácil sería agregar un carácter final a la cadena antes y ajustar la longitud como entonces. SELECT LEN (col + '~') - LEN (REPLACE (col, 'Y', '') + '~')
domenicr

3
Si le preocupan los espacios finales, utilice la función DATALENGTH en su lugar.
StevenWhite

2
@StevenWhite DATALENGTH devuelve el número de bytes utilizados. Entonces NVARCHAR se duplicará.
Domingo

18

Esto me dio resultados precisos cada vez ...

Esto está en mi campo Stripes ...

Amarillo, amarillo, amarillo, amarillo, amarillo, amarillo, negro, amarillo, amarillo, rojo, amarillo, amarillo, amarillo, negro

  • 11 Amarillas
  • 2 negro
  • 1 rojo
SELECT (LEN(Stripes) - LEN(REPLACE(Stripes, 'Red', ''))) / LEN('Red') 
  FROM t_Contacts

¡Esta es una forma muy inteligente! Gracias
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 Esto mejora la segunda sugerencia de @nickf para que realmente le diga el número de instancias de una cadena, incluso si la cadena que está buscando tiene más de 1 carácter
Kevin Heidt

La edición de @ domenicr ha roto esta respuesta y mi edición fue rechazada. La división debe ser por LEN(@StringToFind).
Jamie Kitson

@jamiek disculpas He enviado el código corregido, pero no sé por qué se rechazó tu edición.
Domingo

@domenicr Debes volver al código original, tu edición complica el código sin ningún propósito, @StringToFindnunca va a ser nulo o vacío.
Jamie Kitson

@JamieKitson Veo lo contrario. Verificar una división por cero es un principio de las mejores prácticas. Además, contar el número de espacios en Field To Searchobtendría una división por cero porque Len(' ')devuelve cero.
domenicr

2

Quizás algo como esto ...

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

1

La forma más sencilla es utilizando la función de Oracle:

SELECT REGEXP_COUNT(COLUMN_NAME,'CONDITION') FROM TABLE_NAME

1

Esto devolverá el número de ocurrencia de N

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


0

prueba esto

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

0

Prueba esto. Determina el no. de apariciones de un solo carácter, así como las apariciones de subcadena en la cadena 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

Si desea contar la cantidad de instancias de cadenas con más de un carácter, puede usar la solución anterior con expresiones regulares, o esta solución usa STRING_SPLIT, que creo que se introdujo en SQL Server 2016. También necesitará compatibilidad nivel 130 y 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

La segunda respuesta proporcionada por nickf es muy inteligente. Sin embargo, solo funciona para una longitud de carácter de la subcadena de destino de 1 e ignora los espacios. Específicamente, había dos espacios iniciales en mis datos, que SQL elimina de manera útil (no sabía esto) cuando se eliminan todos los caracteres en el lado derecho. Lo que significaba que

" John Smith"

generó 12 usando el método de Nickf, mientras que:

"Joe Bloggs, John Smith"

generado 10, y

"Joe Bloggs, John Smith, John Smith"

Generado 20.

Por lo tanto, modifiqué la solución ligeramente a lo siguiente, lo que me funciona:

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

¡Estoy seguro de que alguien puede pensar en una mejor manera de hacerlo!


0

También puedes probar esto

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

Salida:

ingrese la descripción de la imagen aquí


0

La siguiente solución ayuda a encontrar ningún carácter presente en una cadena con una limitación:

1) usando SELECT LEN (REPLACE (myColumn, 'N', '')), pero limitación y salida incorrecta en la siguiente condición:

SELECT LEN (REPLACE ('YYNYNYYNNNYYNY', 'N', ''));
--8 --Correcto

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

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

2) Pruebe con la siguiente solución para una salida correcta:

  • Cree una función y modifíquela según los requisitos.
  • Y llame a la función como se indica a continuación

seleccione dbo.vj_count_char_from_string ('123a123a12', '2');
--2 --Correcto

seleccione dbo.vj_count_char_from_string ('123a123a12', 'a');
--2 --Correcto

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

Si necesita contar el carácter en una cadena con más de 2 tipos de caracteres, puede usar en lugar de 'n' -algún operador o expresión regular de los caracteres aceptar el carácter que necesita.

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

-1

Esto es lo que usé en Oracle SQL para ver si alguien estaba pasando un número de teléfono con el formato correcto:

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

La primera parte verifica si el número de teléfono tiene solo números y el guión y la segunda parte verifica que el número de teléfono solo tenga dos guiones.


¿Qué tiene que ver esta pregunta con los números de teléfono? También está pidiendo una solución T-SQL ...
Ben

-1

por ejemplo, para calcular las instancias de recuento del carácter (a) en la columna SQL -> el nombre es el nombre de la columna '' (y en doblequote está vacío, reemplazo a con nocharecter @ '')

seleccione len (nombre) - len (reemplace (nombre, 'a', '')) de PRUEBA

seleccione len ('YYNYNYYNNNYYNY') - len (reemplace ('YYNYNYYNNNYYNY', 'y', ''))

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.