2009-09-21 2 views
5

Ich habe eine Situation, in der ich Datensätze auf einer Seite anzeigen, und ich brauche eine Möglichkeit für den Benutzer, eine Teilmenge dieser Datensätze auf einer anderen Seite angezeigt werden. Diese Datensätze werden nirgendwo gespeichert, es ist eine dynamisch generierte Sache. Ich weiß, dass ich jquery verwenden könnte, um einen kommagetrennten Wert zu meiner anderen Webseite zu übergeben, aber ich bin nicht sicher, was der beste Weg ist, um zu sagen, wo uniqueid in dieser Liste von ids nicht in einer Tabelle usw. ist Ich weiß, ich könnte das Sql dynamisch mit einem Haufen Ors konstruieren, aber das scheint ein Hack zu sein. hat jemand andere Vorschläge?Vergleichen einer Spalte mit einer Liste von Werten in t-sql

+1

http://stackoverflow.com/questions/878833/ –

Antwort

3

dies ist die beste Quelle:

http://www.sommarskog.se/arrays-in-sql.html

eine Split-Funktion erstellen, und verwenden Sie es mögen:

SELECT 
    * 
    FROM YourTable y 
    INNER JOIN dbo.splitFunction(@Parameter) s ON y.ID=s.Value 

I prefer the number table approach

Für diese Methode arbeiten zu können, benötigen diese eine Zeittabelle Setup zu tun:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number 
    INTO Numbers 
    FROM sys.objects s1 
    CROSS JOIN sys.objects s2 
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number) 

Sobald die Zahlen Tabelle eingerichtet ist, diese Funktion erstellen:

CREATE FUNCTION [dbo].[FN_ListToTable] 
(
    @SplitOn char(1)  --REQUIRED, the character to split the @List string on 
    ,@List  varchar(8000)--REQUIRED, the list to split apart 
) 
RETURNS TABLE 
AS 
RETURN 
(

    ---------------- 
    --SINGLE QUERY-- --this will not return empty rows 
    ---------------- 
    SELECT 
     ListValue 
     FROM (SELECT 
        LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue 
        FROM (
          SELECT @SplitOn + @List + @SplitOn AS List2 
         ) AS dt 
         INNER JOIN Numbers n ON n.Number < LEN(dt.List2) 
        WHERE SUBSTRING(List2, number, 1) = @SplitOn 
      ) dt2 
     WHERE ListValue IS NOT NULL AND ListValue!='' 

); 
GO 

Sie können nun einfach eine aufgespalten CSV-String in eine Tabelle und kommen sie darauf:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,') 

OUTPUT:

ListValue 
----------------------- 
1 
2 
3 
4 
5 
6777 

(6 row(s) affected) 

Sie können in einer CSV-Zeichenfolge übergeben, in ein Verfahren, Prozess und nur die Zeilen für die gegebene IDs:

SELECT 
    y.* 
    FROM YourTable y 
     INNER JOIN dbo.FN_ListToTable(',',@GivenCSV) s ON y.ID=s.ListValue 
0

Sie können die Lösung Joel Spolsky recently gave für dieses Problem verwenden.

SELECT * FROM MyTable 
WHERE ',' + 'comma,separated,list,of,words' + ',' 
    LIKE '%,' + MyTable.word + ',%'; 

Diese Lösung ist clever, aber langsam. Die bessere Lösung ist es, die durch Komma getrennte Zeichenfolge, spalten und eine dynamische SQL-Abfrage mit dem IN() Prädikat, das Hinzufügen eines Abfrageparameter Platzhalter für jedes Element in der Liste der Werte konstruieren:

SELECT * FROM MyTable 
WHERE word IN (?, ?, ?, ?, ?, ?, ?, ?); 

Die Anzahl der Platzhalter ist, was Sie müssen bestimmen, wann Sie Ihre kommagetrennte Zeichenfolge aufteilen. Übergeben Sie dann einen Wert aus dieser Liste pro Parameter.

Wenn Sie zu viele Werte in der Liste haben und machen eine lange IN() Prädikat unhandlich ist, dann die Werte in eine temporäre Tabelle einfügen, und JOIN gegen Ihre Haupttabelle:

CREATE TEMPORARY TABLE TempTableForSplitValues (word VARCHAR(20)); 

...split your comma-separated list and INSERT each value to a separate row... 

SELECT * FROM MyTable JOIN TempTableForSplitValues USING (word); 

auch viele andere ähnliche sehen Fragen über SO, einschließlich:

+0

Das erstgenannte „Gerät“ ist mindestens 30 Jahre alt (es ist älter als SQL selbst). Es scheint nicht angemessen, es nach einer zeitgenössischen Person umzubenennen. – RBarryYoung

+0

Fair genug. Ich werde den Satz umschreiben. –

Verwandte Themen