2014-06-05 40 views
2

我有特色(向上20)的列表查詢結/鏈接/橋接表,列的數據作爲報頭

SpecialtyID Description 
------------------------ 
1   Specialty1    
2   Specialty2 
3   Specialty3 

我有提供者(50向上)

ProviderID Name 
------------------------ 
1   Tom    
2   Maria 
3   Pat 
的列表

每個供應商可以有多個專業,每個專業可以有多個供應商 - 所以一個多對多的關係。

我有一個名爲SpecialtyProvider的聯結/鏈接/橋表,如果我用下面的查詢簡單地查詢鏈接表,我會得到下表。

SELECT SpecialtyID, ProviderID FROM SpecialtyProvider 

SpecialtyID ProviderID 
------------------------ 
1   1    
2   1 
3   1 
1   2    
2   2 
3   3 

我想這樣做,是拉出格式化像這樣的數據:

SpecialtyID ProviderID=1 ProviderID=2 ProviderID=3 ProviderID=x 
----------------------------------------------------------- 
1   true   true   NULL 
2   true   true   NULL 
3   true   NULL   true 

一旦我能夠正確格式化數據,我會傾入ASP的ListView這一點。

我不太確定如何繼續。我已經閱讀了100篇關於PIVOT命令的不同版本的帖子,但是我沒有一個聚合函數,但是我還沒有能夠使任何其他示例/解決方案/分組有意義。

回答

2

如果您需要在不使用聚合的情況下進行透視,通常可以使用MAX(實際上,您將單個值的MAX取爲相同的值)。

select SpecialtyID, case when [1] is not null then 'true' end 'ProviderID=1', 
        case when [2] is not null then 'true' end 'ProviderID=2', 
        case when [3] is not null then 'true' end 'ProviderID=3' 
from (
    select s.SpecialtyID, s.Description, sp.ProviderID 
    from Specialty s 
    join SpecialtyProvider sp on sp.SpecialtyID = s.SpecialtyID 
    ) x 
pivot( 
    MAX(Description) 
    for ProviderID in ([1],[2],[3]) 
    ) pvt 

SQL Fiddle

然而,它也可以得到相同的結果,而無需使用PIVOT可言:

select s.SpecialtyID, 
Max(case when sp.ProviderID = 1 then 'true' end) 'ProviderID=1', 
Max(case when sp.ProviderID = 2 then 'true' end) 'ProviderID=2', 
Max(case when sp.ProviderID = 3 then 'true' end) 'ProviderID=3' 
from Specialty s 
join SpecialtyProvider sp on sp.SpecialtyID = s.SpecialtyID 
group by s.SpecialtyID 

我覺得這更容易閱讀,它可能會更快,以及。

SQL Fiddle

說了這麼多,你可能要重新考慮你的UI。桌子寬50列,對用戶來說很難處理。過濾數據可能是有意義的,因此用戶只能查看它的特定部分。另外,如果您處理的是可變數量的提供程序,將所有數據提交到Web服務器並在您的ASP代碼隱藏中處理它是有意義的。

+0

這是一個完美的解決方案,謝謝。不過,我認爲您對重新審視用戶界面的評論可能更有幫助。問題場景的出現是有人在我的桌子上放了一張電子表格,然後說:「做出這樣的事情」,我陷入了試圖做到這一點的狀態,並且真正考慮了提供底層信息的最佳方式中。 – FreeMars

1

以下博客文章介紹了動態數據透視的概念,您不必指定列以解決提供商的X因素。 http://beyondrelational.com/modules/2/blogs/70/posts/10840/dynamic-pivot-in-sql-server-2005.aspx

我花了一點時間並打印出生成的SQL。這就是我想要解決上面的例子。

IF (OBJECT_ID(N'dynamic_pivot', N'P') IS NOT NULL) 
DROP PROCEDURE dynamic_pivot 
GO 

CREATE PROCEDURE dynamic_pivot 
(
    @select VARCHAR(2000) 
, @PivotCol VARCHAR(100) 
, @Summaries VARCHAR(100) 
, @GenerateScript BIT = 1 
) 
AS 
BEGIN 
SET NOCOUNT ON ; 
DECLARE @pivot VARCHAR(MAX) 
    , @sql VARCHAR(MAX) 
SELECT @select = REPLACE(@select, 'SELECT ', 
          'SELECT ' + @PivotCol + ' AS pivot_col, ') 


CREATE TABLE #pivot_columns 
(
    pivot_column VARCHAR(100) 
) 

SELECT @sql = 'SELECT DISTINCT pivot_col FROM (' + @select + ') AS t' 

INSERT INTO #pivot_columns 
     EXEC (@sql 
      ) 

SELECT @pivot = COALESCE(@pivot + ',', '') + '[' + pivot_column + ']' 
FROM #pivot_columns 

SELECT @sql = ' 
SELECT * 
FROM 
(
    ' + @select + ' 
) AS t 
PIVOT 
(
    ' + @Summaries + ' for pivot_col in (' + @pivot + ') 
) AS p' 
PRINT @sql 
EXEC(@sql) 
END 
GO 

EXEC [dbo].[dynamic_pivot] @select = 'SELECT SpecialtyID, 1 AS hasSpecialty FROM SpecialtyProvider', -- varchar(2000) 
@PivotCol = 'ProviderID', -- varchar(100) 
@Summaries = 'COUNT(hasSpecialty)' -- varchar(100) 

是在SSMS顯示在消息窗口結果查詢如下:

SELECT * 
FROM 
(
    SELECT ProviderID AS pivot_col, SpecialtyID, 1 AS hasSpecialty FROM SpecialtyProvider 
) AS t 
PIVOT 
(
    COUNT(hasSpecialty) for pivot_col in ([1],[2],[3]) 
) AS p 

您可以修改這個給你了所需的列名和值。