How do I use a comma separated list of values as a filter in T-SQL?

后端 未结 10 1509
無奈伤痛
無奈伤痛 2021-02-09 14:03

I have a basic SQL query, starting with:

SELECT top 20 application_id, [name], location_id FROM apps

Now, I would like to finish it so that it

相关标签:
10条回答
  • 2021-02-09 14:23

    You are asking different questions here. This is the answer to your original question (about the ternary operator, but as you can see, you don't need anything like a ternary operator for this):

    SELECT top 20 application_id, [name], location_id 
    FROM apps
    WHERE @lid = 0 OR location_id IN (@lid)
    

    But that was before we knew that @lid was a varchar and could contain different comma separated values.

    Well, this (about the csv) is another question which has been asked here before:

    Passing an "in" list via stored procedure
    T-SQL stored procedure that accepts multiple Id values

    0 讨论(0)
  • 2021-02-09 14:23

    See this entry in my blog:

    • IN with a comma separated list: SQL Server

    If your @lid is a comma-delimited list of integers, use this:

    WITH    cd AS
            (
            SELECT  1 AS first, CHARINDEX(',', @lid, 1) AS next
            UNION ALL
            SELECT  next + 1, CHARINDEX(',', @lid, next + 1)
            FROM    cd
            WHERE   next > 0
            ),
            lid AS
            (
            SELECT  CAST(SUBSTRING(@lid, first, CASE next WHEN 0 THEN LEN(@lid) + 1 ELSE next END - first)AS INT) AS id
            FROM    cd
            )
    SELECT  d.*
    FROM    (
            SELECT  DISTINCT id
            FROM    lid
            ) l
    JOIN    apps a
    ON      a.location_id = l.id
            AND @lid <> '0'
    UNION ALL
    SELECT  *
    FROM    apps a
    WHERE   @lid = '0'
    

    This is much more efficient than using OR constructs.

    0 讨论(0)
  • 2021-02-09 14:25

    Try using Case, which serves the purpose of an IIF or a ternary operator. Please check this link http://msdn.microsoft.com/en-us/library/ms181765.aspx

    cheers

    0 讨论(0)
  • 2021-02-09 14:27

    While it is not exactly a best practice to use 1=1, it does the trick here.

    SELECT top 20 application_id, [name], location_id FROM apps
    WHERE
      (@lid > 0 and @lid = location_id)
    or
      (isnull(@lid, 0) <= 0 and 1=1)
    
    0 讨论(0)
  • 2021-02-09 14:29

    One way is to split the string on the commas, strip out the spaces and insert the values into a temporary table. Then you can join your query against the temp table.

    This is a T-SQL code snippet that splits a comma-separated list and inserts the members into a temporary table. Once you've populated the table you can join against it.

    -- This bit splits up a comma separated list of key columns
    -- and inserts them in order into a table. 
    --
    if object_id ('tempdb..#KeyCols') is not null
        drop table #KeyCols
    
    create table #KeyCols (
          ,KeyCol           nvarchar (100)
    )
    
    set @comma_pos = 0
    set @len = len(@KeyCols)
    while @len > 0 begin
        set @comma_pos = charindex(',', @KeyCols)
        if @comma_pos = 0 begin
            set @KeyCol = @KeyCols
            set @KeyCols = ''
        end else begin
            set @KeyCol = left (@KeyCols, @comma_pos - 1)
            set @KeyCols = substring(@KeyCols, 
                                     @comma_pos + 1, 
                                     len (@KeyCols) - @comma_pos)
        end
        insert #KeyCols (KeyCol)
        values (@KeyCol)
        set @len = len (@KeyCols)
    end
    
    0 讨论(0)
  • 2021-02-09 14:30

    Assuming @locid & @lid are the same, I'm going to use @locid... The following would work. I've split it up to keep it looking good on SO.

    SELECT application_id, [name], location_id 
    FROM apps
    WHERE
      ( 
        @locid = 0
        OR 
        CHARINDEX
        ( 
          ',' + CAST(location_id AS VARCHAR(50)) + ','
          , 
          ',' + @locid + ','
          , 
          0 
        ) > 0
      )
    
    0 讨论(0)
提交回复
热议问题