Find primary key from one table in comma separated list

后端 未结 4 1156
情话喂你
情话喂你 2020-12-12 06:29

I\'ve been given the task at work of creating a report based on a very poorly designed table structure.

Consider the following two tables. They contain techniques t

相关标签:
4条回答
  • 2020-12-12 06:35

    Using this function

    Create FUNCTION F_SplitAsIntTable 
    (
    @txt varchar(max)
    )
    RETURNS 
    @tab TABLE 
    (
     ID int
    )
    AS
    BEGIN
        declare @i int
        declare @s varchar(20)
        Set @i = CHARINDEX(',',@txt)
        While @i>1
            begin
              set @s = LEFT(@txt,@i-1)
              insert into @tab (id) values (@s)
              Set @txt=RIGHT(@txt,Len(@txt)-@i)
              Set @i = CHARINDEX(',',@txt)
            end
        insert into @tab (id) values (@txt) 
        RETURN 
    END
    

    You can query like this

    declare  @a Table  (id int,Name varchar(10),Kind Varchar(100))
    insert into @a values (1,'test','1,2,3,4'),(2,'test2','1,2,3,5'),(3,'test3','3,5')
    
    Select a.ID,Name
    from @a a
    cross apply F_SplitAsIntTable(a.Kind) b 
    where b.ID=2
    
    0 讨论(0)
  • 2020-12-12 06:39

    I think this query looks cleaner:

    SELECT p.*, 
    t.Technique as ParsedTechnique
    FROM Personnel p
    JOIN Techniques t
    ON CHARINDEX((','+CAST(t.id as varchar(10))+','), (','+p.technique+',')) > 0
    WHERE t.id ='1';
    

    You can just change the WHERE t.id = to whatever TechniqueId you need.

    Fiddle Here

    0 讨论(0)
  • 2020-12-12 06:42

    The first comment under the question provided the link to the answer. Here's what I ended up going with:

    WHERE
       p.Technique LIKE '%,29,%' --middle
          OR
       p.Technique LIKE '29,%' --start
          OR
       p.Technique LIKE '%,29' --end
          OR 
       p.Technique =  '29' --single (good point by Cheran S in comment)
    

    At initial glance I thought it wouldn't work, but clever use of % made it not match ids like 129, etc.

    0 讨论(0)
  • 2020-12-12 06:49

    One of the problems you have to prevent is prevent "1" from matching "10" and "11". For this, you want to be sure that all values are delimited by the separator (in this case a comma).

    Here is a method using like that should work effectively (although performance will not be so great):

    SELECT p.*, t.Technique as ParsedTechnique
    FROM Personnel p join
         Techniques t
         on ','+p.technique+',' like '%,'+cast(t.id as varchar(255))+',%'
    WHERE t.id = 1;
    

    If performance is an issue, then fix your data structure an include a PersonTechniques table so you can do a proper join.

    0 讨论(0)
提交回复
热议问题