2009-09-21 9 views
5

Tengo una situación en la que estoy mostrando registros en una página, y necesito una manera para que el usuario seleccione un subconjunto de esos registros para mostrar en otra página. Estos registros no se almacenan en ningún lugar, es una cosa generada dinámicamente. Sé que podría usar jquery para pasar un valor separado por comas a mi otra página web, pero no estoy seguro de cuál es la mejor manera de decir en sql dónde está uniqueid en esta lista de identificadores que no están en una tabla, etc. Sé que podría construir dinámicamente el sql con un grupo de ors, pero parece un truco. ¿Alguien más tiene alguna sugerencia?comparando una columna con una lista de valores en t-sql

+1

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

Respuesta

3

esta es la mejor fuente:

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

crear una función de división, y usarlo como:

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

I prefer the number table approach

Para que este método funcione, es necesario realizar esta configuración mesa de una vez:

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 vez que los números de la tabla está configurado, crear esta función:

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 

Ahora puede dividir fácilmente un cadena CSV en una mesa y se unen en él:

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

SALIDA:

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

(6 row(s) affected) 

Tu puede pasar una serie de CSV en un procedimiento de proceso y sólo las filas de las identificaciones dadas:

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

Puede utilizar la solución Joel Spolsky recently gave para este problema.

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

Esa solución es inteligente pero lenta. La mejor solución es dividir la cadena separada por comas, y construir una consulta SQL dinámico con el IN() predicado, la adición de un marcador de posición de parámetro de consulta para cada elemento en la lista de valores:

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

el número de marcadores de posición es lo tienes que determinar cuándo dividiste tu cadena separada por comas. Luego pase un valor de esa lista por parámetro.

Si usted tiene demasiados valores en la lista y haciendo mucho IN() predicado es difícil de manejar, a continuación, inserta los valores en una tabla temporal, y JOIN en contra de su mesa principal:

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

también ver muchos otros similares preguntas sobre SO, incluyendo:

+0

El mencionado en primer lugar "dispositivo" es por lo al menos 30 años de edad (es anterior incluso al propio SQL). No parece apropiado cambiarle el nombre a una persona contemporánea. – RBarryYoung

+0

Bastante justo. Reescribiré la oración. –

Cuestiones relacionadas