2009-09-21 9 views
5

Ho una situazione in cui sto visualizzando i record su una pagina e ho bisogno di un modo per l'utente di selezionare un sottoinsieme di quei record da visualizzare su un'altra pagina. Questi record non vengono memorizzati da nessuna parte, quindi è una cosa generata dinamicamente. So che potrei usare jquery per passare un valore separato da virgole alla mia altra pagina web, ma non sono sicuro di quale sia il modo migliore di in sql dire dove uniqueid è in questa lista di id non in una tabella ecc. I so che potrei costruire dinamicamente lo sql con un gruppo di ors, ma sembra un trucco. Qualcun altro ha qualche suggerimento?confrontando una colonna con un elenco di valori in t-sql

+1

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

risposta

3

Questa è la migliore fonte:

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

creare una funzione split, e utilizzarlo come:

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

I prefer the number table approach

Per questo metodo funzioni, è necessario fare questa configurazione tavolo una volta:

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) 

Una volta che i numeri della tabella viene istituito, a creare questa funzione:

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 

Si può ora facilmente dividere un stringa CSV in una tabella e unirsi su di esso:

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

USCITA:

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

(6 row(s) affected) 

tuo può passare in una stringa CSV in una procedura e di processo solo le righe per gli ID indicati:

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

Per questo problema è possibile utilizzare la soluzione Joel Spolsky recently gave.

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

Questa soluzione è intelligente ma lenta. La soluzione migliore è quella di dividere la stringa separata da virgole, e costruire una query SQL dinamico con la IN() predicato, aggiungendo un segnaposto parametro di query per ogni elemento nell'elenco di valori:

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

il numero di segnaposto è quello devi determinare quando dividi la stringa separata da virgola. Quindi passare un valore da quella lista per parametro.

Se si dispone di troppi valori nella lista e facendo un lungo IN() predicato è ingombrante, quindi inserire i valori in una tabella temporanea, e JOIN contro la vostra tabella 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); 

vedono anche molti altri simili domande sul SO, tra cui:

+0

Il "dispositivo" menzionato per primo è AT Almeno 30 anni (è precedente persino a SQL stesso). Non sembra appropriato rinominarlo dopo una persona contemporanea. – RBarryYoung

+0

Abbastanza giusto. Riformulerò la frase. –

Problemi correlati