如何在ON中使用IN()连接表?

时间:2019-11-19 12:49:11

标签: sql

我有两个桌子

用户

id | name | category
1  | test | [2,4]

类别

id | name
1  | first
2  | second
3  | third
4  | fourth

现在我需要同时加入这两个表并获取数据:

name | category
test | second, fourth

我尝试过:

select u.name as name, c.name as category 
from user 
 INNER JOIN category on(c.id in (u.category))

但是它不起作用。

1 个答案:

答案 0 :(得分:1)

正如其他人所建议的那样,如果您对该数据库的设计有任何控制权,请不要在user.category中存储多个值,而应在两者之间使用桥接表来映射一个或多个类别值每个用户记录。

但是,如果您无法重新设计数据库,则可以通过以下方法获得所需的结果。首先,让我们创建一些测试数据:

create table [user]
(
    id int,
    [name] varchar(50),
    category varchar(50) -- I'm assuming this is a string type
)

create table category
(
    id int,
    [name] varchar(50)
)

insert into [user] values 
(1,'test','[2,4]'),
(2,'another test','[1,2,4]'),
(3,'more test','[1,3,2,4]')

insert into category values 
(1,'first'),
(2,'second'),
(3,'third'),
(4,'fourth');

然后,您可以将CTE与split_string一起使用,以将各个类别值分开,将它们与它们的名称结合在一起,然后使用for xml将它们重新组合为一个逗号分隔的值:

with r as
(
    select
        u.[name] as username,
        cat.id,
        cat.[name] as categoryname
    from [user] u
    outer apply
    (
        select value from string_split(substring(u.category,2,len(u.category)-2),',')
    ) c
    left join category cat on c.value = cat.id
)

select
    r.username,
    stuff(
        (select ',' + categoryname
         from r r2
         where r.username = r2.username
         order by r2.id
         for xml path ('')), 1, 1, '') as categories
from r
group by r.username

给出所需的输出:

/-----------------------------------------\
|  username   | categories                |
|-------------|---------------------------|
|another test | first,second,fourth       |
|more test    | first,second,third,fourth |
|test         | second,fourth             |
\-----------------------------------------/

我在这里做几个假设:

  • 您正在使用MS SQL Server
  • 类别值始终以[开头,以]结尾,并且只包含一个逗号分隔的字符串,其中包含值类别ID。