我有一份专业清单(超过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命令的不同变体的帖子,但是我没有集合功能,我还没有能够让任何其他示例/解决方案/分组有意义。
答案 0 :(得分: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
但是,如果不使用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
我发现这更容易阅读,也可能更快。
尽管如此,您可能想重新考虑您的用户界面。具有50列宽的表将对于用户来说难以处理。过滤数据可能是有意义的,因此用户只能查看数据的特定部分。此外,如果您正在处理可变数量的提供程序,将所有数据提取到Web服务器并在ASP代码隐藏中处理它可能是有意义的。
答案 1 :(得分: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
您可以对其进行修改,以提供所需的列名和值。