2010-06-01 68 views
1

我有一個非常簡單的查詢,我需要pivoted,但我還沒有一個線索如何將它從我已閱讀的文獻中變成一個數據透視表。我讀過的所有內容涉及硬編碼列或太複雜。它必須更簡單,否則我無法掌握CTE。如何爲這個簡單案例創建樞軸查詢?

該查詢是他們有權訪問的用戶名和客戶端的列表。所以我有這樣的:

user client 
1 a 
1 b 
1 c 
2 a 
2 d 
3 a 
3 d 
3 e 
3 f 

客戶端的總數可能在20左右左右。一些用戶可以訪問所有客戶端,其他用戶只能訪問一兩個。我想看到的是:

user a b c d e f 
1 x x x 
2 x x 
3 x x x x 

這涉及到三個表:用戶表,客戶表,團結用戶與他們的客戶交叉引用表(權限)。

我試過類似下面的東西,但它顯然不工作(甚至編譯)。

with usersclients(user_name, clients, client_code) 
as 
(
select users.user_name 
from clients cli 
    left join 
    (select u.user_id, user_name, c.client_id, client_code, client_name 
    from permissions p inner join clients c on p.client_id = c.client_id 
    inner join users u on u.user_id = p.user_id 
) user 
    on user.client_id = cli.client_id 
) 
select * 
from usersclients 
pivot (max(client_code) for client_code in (select client_code from clients)) as P 

任何線索最受讚賞!

回答

2

我相信SQL服務器要求你明確地指定你的數據透視表中的每一列。所以,從原始查詢下面的代碼片段是不允許的:

for client_code in (select client_code from clients)

你必須明確地命名每個客戶端的代碼。

編輯:這是一個示例支點,以適應你的例子:

WITH Permit (Usr, Client) AS 
(
    SELECT 1, 'a' UNION ALL 
    SELECT 1, 'b' UNION ALL 
    SELECT 1, 'c' UNION ALL 
    SELECT 2, 'a' UNION ALL 
    SELECT 2, 'd' UNION ALL 
    SELECT 3, 'a' UNION ALL 
    SELECT 3, 'd' UNION ALL 
    SELECT 3, 'e' UNION ALL 
    SELECT 3, 'f' 
) 
SELECT p.* 
FROM Permit 
    PIVOT (MAX(Client) FOR Client IN (a, b, c, d, e, f)) p 

編輯:這是一個動態的SQL選項;你可能會把它放在TVF中:

--source table 
CREATE TABLE #Permit (Usr int, Client char(1)); 
INSERT INTO #Permit (Usr, Client) 
SELECT 1, 'a' UNION ALL 
SELECT 1, 'b' UNION ALL 
SELECT 1, 'c' UNION ALL 
SELECT 2, 'a' UNION ALL 
SELECT 2, 'd' UNION ALL 
SELECT 3, 'a' UNION ALL 
SELECT 3, 'd' UNION ALL 
SELECT 3, 'e' UNION ALL 
SELECT 3, 'f'; 


DECLARE @Command nvarchar(max); 
SET @Command = ''; 

--prepare the list of columns 
SELECT @Command = @Command + ', ' + CONVERT(nvarchar(10), Client) 
FROM (SELECT DISTINCT Client FROM #Permit) x; 

--chop the extra leading comma off 
SET @Command = SUBSTRING(@Command, 3, LEN(@Command)); 

--prepare the rest of the pivot command 
SET @Command = N' 
SELECT p.* 
FROM #Permit 
    PIVOT (MAX(Client) FOR Client IN (' + @Command + ')) p'; 

--execute the command 
EXEC sp_executesql @Command; 


DROP TABLE #Permit; 
+0

謝謝邁克爾 - 這一定是爲什麼所有的樣本明確地列出列!這是一個真正的PITA,當你可以有幾十個客戶... – Larry 2010-06-01 14:53:16

+0

同意。您可以將查詢形成爲字符串,並且如果您有許多客戶端,則使用'sp_executesql'。我很快就會更新我的答案。 – 2010-06-01 14:59:12

+0

所以唯一的方法是使用動態SQL?我已經看到了一些例子。我嘗試使用上述方法,但不幸的是,我有成千上萬的用戶!編碼需要一段時間。 也許另一個答案是隻將用戶/客戶端列表導入Excel,並讓Excel創建數據透視表。 Excel似乎更擅長這種事情。 – Larry 2010-06-01 15:03:53