2016-03-08 107 views
1

我已经在网上看了几天了如何在sql server上使用STUFF,我看到的大多数例子都只涉及到两个表,我的查询是通过3个表,我只是可以“弄不明白在这里工作是没有STUFF功能,让我所有我想要的数据查询:SQL Server字符串Concat与东西

select c.category_name,r.role_name 
from categories as c 
join role_categ as rc on c.category_id=rc.category_id 
join roles as r on r.role_id=rc.role_id 
where rc.c_read='1'; 

These are the results

我想要的是你有一个CATEGORY_NAME然后标识希望所有的role_names在第一排中的一个单元中:

 
BCM-Télécopieur-photocopieur Admin,Administation 

在这里我有什么用那东西的功能,但不工作仅仅指刚给我同桌的其他查询

select c.category_name,STUFF((
    select ','+r.role_name 
    from roles as r 
    where rc.role_id=r.role_id 
    for xml path('')),1,1,'') 
from role_categ as rc 
join categories as c on c.category_id=rc.category_id 

任何帮助,将不胜感激。

+0

尝试增加'选择DISTINCT'主查询和改变'''到-' – lad2025

+3

'STUFF'没有按不做任何字符串连接。 'FOR XML'在这里做了繁重的工作,产生了一个像',abc,def,ghi'这样的字符串。 “STUFF”所做的就是删除那个逗号。 –

回答

1

下面是我想到的一个版本。 @GiorgosBetsos是正确的,JOIN需要被转移到内部查询。我不知道他为什么仍然出现重复,但预期以下查询返回的数据:

-- Set up the data 
DECLARE @roles TABLE (role_id INT, role_name VARCHAR(20)) 
DECLARE @role_categories TABLE (category_id INT, role_id INT) 
DECLARE @categories TABLE (category_id INT, category_name VARCHAR(20)) 

INSERT INTO @roles (role_id, role_name) VALUES (1, 'Admin'), (2, 'Administration'), (3, 'Tech') 
INSERT INTO @categories (category_id, category_name) VALUES (1, 'Consultant'), (2, 'FTP'), (3, 'Logicals') 
INSERT INTO @role_categories (category_id, role_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 1) 

-- The query 
SELECT 
    C.category_name, 
    STUFF((
     SELECT ',' + R.role_name 
     FROM 
      @role_categories RC 
     INNER JOIN @roles R ON R.role_id = RC.role_id 
     WHERE 
      RC.category_id = C.category_id AND 
      RC.c_read = 1 
     FOR XML PATH('')), 1, 1, '') 
FROM 
    @categories C 
+0

主查询不会对'role_categ'执行'JOIN',所以你不会有重复。在OP中提到的查询中有一个额外的谓词'c_read ='1'',所以我想你还必须加入'role_categ'。 –

+0

我已将'c_read'添加到内部查询中。我想回答这个问题中的最后一个陈述,所以我错过了那部分。它仍然有效,没有重复。您在查询中只需要一次'role_categ'。 –

1

试试这个:

SELECT DISTINCT c_out.category_name, 
     STUFF((SELECT ',' + r.role_name 
       FROM roles as r 
       INNER JOIN role_categ as rc ON rc.role_id=r.role_id 
       WHERE rc_out.category_id=rc.category_id 
       FOR XML PATH('')),1,1,'') 
FROM role_categ AS rc_out 
JOIN categories AS c_out ON c_out.category_id = rc_out.category_id 
WHERE rc_out.c_read = '1' 

您需要JOINrole_categ表子查询里面,这样就可以关联到category_id。此外,您必须在外部查询中使用DISTINCT才能过滤掉重复的记录。

+0

我认为如果你在内部查询中只有'JOIN',你可以取消'DISTINCT'。 –

+0

@TomH我用我自己的样本数据测试了查询,并且它返回了没有'DISTINCT'的副本。 –

+0

因为我已经运行了我自己的版本和查询的修改版本,而没有'DISTINCT'而没有问题,所以不知道交易是什么。我会在下面发布它作为答案,也许你会发现我错过的东西。 –