it-swarm.com.de

Dabei ist der Wert in der Spalte mit durch Kommas getrennten Werten

Hallo, ich frage mich, wie Sie eine SQL-Anweisung für SQL Server 2008 schreiben, in der Einträge ausgewählt werden, in denen eine Spalte einen Wert enthält. Jetzt ist der Wert in der Spalte eine durch Kommas getrennte Liste (normalerweise - es könnte nur einen Eintrag geben (und kein führendes Komma). ) Was ist beim Überprüfen auf "Ist dieser Wert irgendwo in der Liste enthalten?", zum Beispiel:

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

oder

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

usw

Ich dachte, ich könnte das Schlüsselwort 'IN' als solches verwenden

SELECT id_column FROM table_name WHERE 'Cat' IN COLUMN

dies funktioniert jedoch nicht, da es so aussieht, als könnten Sie dies nur verwenden, um zu überprüfen, ob eine Spalte einen aus einer Reihe von durch Kommas getrennten Wert enthält.

CONTAINS () OR 'LIKE' kann ich auch nicht verwenden, da im obigen Beispiel Werte für 'horse' zurückgegeben würden, da die gesamte Zeichenfolge Pferd in 'Seahorse' enthält und ich nicht nach der Nadel plus suchen kann ein Komma (wenn ich nach "Pferd" suche, wäre die Suche "Pferd") als was, wenn der Eintrag am Ende einer Liste steht? Und ich kann nicht nach einem Komma und einer Nadel suchen (wenn ich nach 'Pferd' suche, wäre das 'Pferd') Was wäre, wenn der Eintrag der erste in der Liste ist? Und ich kann nicht beides als was verwenden, wenn der Eintrag der einzige (einzelne) Eintrag ist?

Danke für jede Hilfe, die jeder geben kann.

Prost.

41
Neaox

Es gibt ein schwieriges Szenario. Wenn ich nach '40' in der Liste '17, 34,400,12 'suche, würde es ", 40" finden und diesen falschen Eintrag zurückgeben. Dies kümmert sich um alle Lösungen:

WHERE (',' + RTRIM(MyColumn) + ',') LIKE '%,' + @search + ',%'
90
tbaxter120
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)
22
gbn
SELECT * FROM TABLENAME WHERE FIND_IN_SET(@search, column)

Wenn sich herausstellt, dass Ihre Spalte zwischen den Listenelementen Leerzeichen enthält, verwenden Sie

SELECT * FROM TABLENAME WHERE FIND_IN_SET(@search, REPLACE(column, ' ', ''))

http://dev.mysql.com/doc/refman/5.0/de/string-functions.html

10
Liquinaut
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 + ',%'

Dies erfordert natürlich einen vollständigen Tabellenscan für jede Suche.

6
Martin Smith

In diesem Fall empfiehlt es sich, die Tabelle so zu normalisieren, dass die durch Kommas getrennten Werte in verschiedenen Zeilen angezeigt werden (erste Normalform 1NF) http://en.wikipedia.org/wiki/First_normal_form

Dazu können Sie eine Nizza-Split-Tabellenwertfunktion in SQL implementieren, indem Sie CLR http://bi-tch.blogspot.com/2007/10/sql-clr-net-function-split.html verwenden mit normalem SQL.

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

Dann können Sie die normalisierte Ausgabe mit cross apply abfragen.

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

Ich habe diese Antwort in einem anderen Forum gefunden, funktioniert einwandfrei ..__ Keine Probleme mit 1 zu finden, wenn es auch eine 10 gibt

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

ich habe es hier gefunden

3
Maurits Weebers
select *
from YourTable
where ','+replace(col, ' ', '')+',' like '%,Cat,%'
2
Mikael Eriksson

Ich habe gerade darüber erfahren, als ich nach einer Lösung für ein ähnliches Problem suchte. SQL hat ein neues Schlüsselwort namens CONTAINS, das Sie verwenden können. Weitere Informationen finden Sie unter http://msdn.Microsoft.com/en-us/library/ms187787.aspx

1
S Ravi Kumar
SELECT * FROM TABLE_NAME WHERE
        (
            LOCATE(',DOG,', CONCAT(',',COLUMN,','))>0 OR
            LOCATE(',CAT,', CONCAT(',',COLUMN,','))>0
        );
0
D3MO

Wenn Sie die IDs und nicht die Zeichenfolgen kennen, gehen Sie folgendermaßen vor:

where mylookuptablecolumn IN (myarrayorcommadelimitedarray)

Stellen Sie nur sicher, dass myarrayorcommadelimitedarray nicht in String-Anführungszeichen gesetzt wird. 

funktioniert, wenn Sie A OR B wünschen, aber nicht UND.

0
stu

Obwohl die knifflige Lösung @ tbaxter120 empfehlenswert ist, aber ich benutze diese Funktion und arbeite wie ein Zauber, pString ist eine begrenzte Zeichenfolge und pDelimiter ist ein Trennzeichen:

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

;

Dann können Sie es beispielsweise in where-Klausel wie folgt aufrufen:

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

Ich hoffe das hilft.

0
QMaster

Der Wert in der Spalte mit durch Kommas getrennten Werten wird mit mehreren durch Kommas getrennten Werten gesucht 

            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 ''%,'[email protected]+ ',%'''

             print @d1
             exec (@d1)
0
Rajesh Kumar

Da Sie nicht wissen, wie viele durch Kommas getrennte Einträge gefunden werden können, müssen Sie möglicherweise eine Funktion mit SQL Server-Funktionen "charindex" und "substring" erstellen. Die von der Funktion zurückgegebenen Werte können in einem 'in'-Ausdruck verwendet werden.

Ihre Funktion kann rekursiv aufgerufen werden oder Sie können eine Schleife erstellen und nach Einträgen suchen, bis keine weiteren Einträge in der Zeichenfolge vorhanden sind. Bei jedem Aufruf der Funktion wird der zuvor gefundene Index als Ausgangspunkt für den nächsten Aufruf verwendet. Der erste Anruf beginnt bei 0.

0
Edwin Dalorzo