2009-09-21 7 views
5

J'ai une situation où j'affiche des enregistrements sur une page, et j'ai besoin d'un moyen pour l'utilisateur de sélectionner un sous-ensemble de ces enregistrements à afficher sur une autre page. Ces enregistrements ne sont stockés nulle part, c'est une chose générée dynamiquement. Je sais que je pourrais utiliser jquery pour transmettre une valeur séparée par des virgules à mon autre page Web, mais je ne suis pas sûr de la meilleure façon de dire dans sql où uniqueid est dans cette liste d'ids pas dans une table etc. sais que je pourrais construire dynamiquement le sql avec un tas de ors, mais cela semble être un hack. quelqu'un d'autre a des suggestions?comparer une colonne à une liste de valeurs dans t-sql

+1

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

Répondre

3

c'est la meilleure source:

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

créer une fonction split, et l'utiliser comme:

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

I prefer the number table approach

Pour que cette méthode fonctionne, vous devez effectuer cette configuration de la table une seule fois:

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) 

Une fois la table des numéros est mis en place, créez cette fonction:

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 

Vous pouvez maintenant facilement diviser un chaîne CSV dans une table et se joindre à elle:

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

SORTIE:

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

(6 row(s) affected) 

Votre peut passer dans une chaîne CSV dans une procédure et un processus uniquement les lignes pour les ID données:

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

Vous pouvez utiliser la solution Joel Spolsky recently gave pour ce problème.

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

Cette solution est intelligente mais lente. La meilleure solution est de diviser la chaîne séparés par des virgules, et de construire une requête SQL dynamique avec le prédicat IN(), l'ajout d'un espace réservé de paramètre de requête pour chaque élément dans la liste des valeurs:

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

Le nombre d'espaces réservés est ce que vous devez déterminer quand vous divisez votre chaîne séparée par des virgules. Passez ensuite une valeur à partir de cette liste par paramètre.

Si vous avez trop de valeurs dans la liste et fait une longue IN() prédicat est peu maniable, puis insérez les valeurs à une table temporaire et JOIN contre votre table principale:

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

voir aussi beaucoup d'autres semblables questions sur SO, dont:

+0

mentionné en premier « dispositif » est à moins de 30 ans (il est même antérieur à SQL lui-même). Il ne semble pas approprié de le renommer après une personne contemporaine. – RBarryYoung

+0

Assez juste. Je vais reformuler la phrase. –

Questions connexes