valor una traer seleccionar repiten repetidos registros registro obtener mayor maximo distintos cuantos contar condicion con columna campo sql sql-server tsql sql-server-2008 csv

sql - una - Donde el valor en la columna contiene valores delimitados por comas



sql contar registros repetidos (13)

Hola, me pregunto cómo escribir una declaración SQL para SQL Server 2008 que selecciona entradas donde una columna contiene un valor, ahora el valor dentro de la columna es una lista delimitada por comas (por lo general, solo podría haber una entrada (y ninguna coma inicial) ) Entonces, ¿qué está comprobando "es este valor contenido en algún lugar dentro de la lista?", por ejemplo:

COLUMN = Cat, Dog, Sparrow, Trout, Cow, Seahorse Does COLUMN contain Cat? YES Does COLUMN contain horse? NO Does COLUMN contain Sheep? NO

o

COLUMN = Mouse Does COLUMN contain Hare? NO Does COLUMN contain Mouse? YES

etc

Estaba pensando que podría usar la palabra clave ''IN'' como tal

SELECT id_column FROM table_name WHERE ''Cat'' IN COLUMN

pero esto no funciona, ya que parece que solo puede usar eso para verificar si una columna contiene uno de una serie de valores delimitados por comas.

Tampoco puedo usar CONTAINS () O ''LIKE'' como este, en el ejemplo anterior devolvería valores para ''horse'' ya que toda la cadena contiene horse en ''Seahorse'', y no puedo buscar la aguja más una coma (si Estoy buscando ''caballo'', la búsqueda sería ''caballo'', ¿y qué pasa si la entrada está al final de la lista? Y no puedo buscar una coma más una aguja (si estoy buscando ''caballo'' la búsqueda sería '', caballo'') como si la entrada es la primera en la lista? Y no puedo usar ambos como ¿qué pasa si la entrada es la única entrada (única)?

Gracias por la ayuda que cualquiera pueda aportar.

Aclamaciones.



Aunque la solución difícil @ tbaxter120 recomendada es buena, pero utilizo esta función y trabajo como un encanto, pString es una cadena delimitada y pDelimiter es un carácter delimitador:

SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER FUNCTION [dbo].[DelimitedSplit] --===== Define I/O parameters (@pString NVARCHAR(MAX), @pDelimiter CHAR(1)) RETURNS TABLE WITH SCHEMABINDING AS RETURN --===== "Inline" CTE Driven "Tally Table" produces values from 0 up to 10,000... -- enough to cover VARCHAR(8000) WITH E1(N) AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ), --10E+1 or 10 rows E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max cteTally(N) AS (--==== This provides the "base" CTE and limits the number of rows right up front -- for both a performance gain and prevention of accidental "overruns" SELECT TOP (ISNULL(DATALENGTH(@pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4 ), cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter) SELECT 1 UNION ALL -- does away with 0 base CTE, and the OR condition in one go! SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter ), cteLen(N1,L1) AS(--==== Return start and length (for use in substring) SELECT s.N1, ---ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000) ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,50000) FROM cteStart s ) --===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found. SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1), Item = SUBSTRING(@pString, l.N1, l.L1) FROM cteLen l ;

Entonces, por ejemplo, puede invocarlo en la cláusula where, como se muestra a continuación:

WHERE [fieldname] IN (SELECT LTRIM(RTRIM(Item)) FROM [dbo].[DelimitedSplit](''2,5,11'', '',''))

Espero que esto ayude.


Como no sabe cuántas entradas delimitadas por comas puede encontrar, puede que necesite crear una función con las funciones ''charindex'' y ''substring'' de SQL Server. Los valores, tal como los devuelve la función, se pueden usar en una expresión ''in''.

Su función puede invocarse recursivamente o puede crear un bucle, buscando entradas hasta que no haya más entradas presentes en la cadena. Cada llamada a la función utiliza el índice encontrado previamente como punto de partida de la próxima llamada. La primera llamada comienza en 0.


Donde el valor en la columna que contiene valores delimitados por comas busca con múltiples comas delimitadas

declare @d varchar(1000)=''-11,-12,10,121'' set @d=replace(@d,'','','',%'''' or '''',''''+a+'''','''' like ''''%,'') print @d declare @d1 varchar(5000)= ''select * from ( select ''''1,21,13,12'''' as a union select ''''11,211,131,121'''' union select ''''411,211,131,1211'''') as t where '''',''''+a+'''','''' like ''''%,''+@d+ '',%'''''' print @d1 exec (@d1)


Encontré esta respuesta en otro foro, funciona perfecto. No hay problemas para encontrar 1 si también hay un 10

WHERE tablename REGEXP "(^|,)@search(,|$)"

Lo encontré aquí


Hay un escenario complicado. Si estoy buscando ''40'' en la lista ''17, 34,400,12 '', entonces encontraría ", 40" y devolvería esa entrada incorrecta. Esto se ocupa de todas las soluciones:

WHERE ('','' + RTRIM(MyColumn) + '','') LIKE ''%,'' + @search + '',%''


La mejor solución en este caso es normalizar su tabla para tener los valores separados por comas en diferentes filas (Primera forma normal 1NF) http://en.wikipedia.org/wiki/First_normal_form

Para eso, puede implementar una buena función de tabla dividida en SQL, usando CLR http://bi-tch.blogspot.com/2007/10/sql-clr-net-function-split.html o usando SQL simple.

CREATE FUNCTION dbo.Split ( @RowData nvarchar(2000), @SplitOn nvarchar(5) ) RETURNS @RtnValue table ( Id int identity(1,1), Data nvarchar(100) ) AS BEGIN Declare @Cnt int Set @Cnt = 1 While (Charindex(@SplitOn,@RowData)>0) Begin Insert Into @RtnValue (data) Select Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1))) Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData)) Set @Cnt = @Cnt + 1 End Insert Into @RtnValue (data) Select Data = ltrim(rtrim(@RowData)) Return END

Luego puede consultar la salida normalizada utilizando cross apply

select distinct a.id_column from MyTable a cross apply dbo.Split(A.MyCol,'','') b where b.Data=''Cat''


Si conoce las identificaciones en lugar de las cadenas, use este enfoque:

where mylookuptablecolumn IN (myarrayorcommadelimitedarray)

Solo asegúrese de que myarrayorcommadelimitedarray no esté entre comillas de cadena.

funciona si quieres A o B, pero no AND.


DECLARE @search VARCHAR(10); SET @search = ''Cat''; WITH T(C) AS ( SELECT ''Cat, Dog, Sparrow, Trout, Cow, Seahorse'' ) SELECT * FROM T WHERE '', '' + C + '','' LIKE ''%, '' + @search + '',%''

Por supuesto, esto requerirá un escaneo de tabla completo para cada búsqueda.



SELECT * FROM TABLE_NAME WHERE ( LOCATE('',DOG,'', CONCAT('','',COLUMN,'',''))>0 OR LOCATE('',CAT,'', CONCAT('','',COLUMN,'',''))>0 );


WHERE MyColumn LIKE ''%,'' + @search + '',%'' --middle OR MyColumn LIKE @search + '',%'' --start OR MyColumn LIKE ''%,'' + @search --end OR MyColumn = @search --single (good point by Cheran S in comment)


select * from YourTable where '',''+replace(col, '' '', '''')+'','' like ''%,Cat,%''