2016-03-08 68 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'而沒有問題,所以不知道交易是什麼。我會在下面發佈它作爲答案,也許你會發現我錯過的東西。 –