我有两个主表CompanyMaster
,ActivityMaster
用于子表CompanyActivities
ActivityMaster
ACTIVITYID ACTIVITYNAME
A1 testActivity
A2 someActivity
A3 otheractivity
A4 someotheractivity
A5 anyotheractivity
CompanyMaster
COMPANYID COMPANYNAME
C1 testcompany
C2 ACompany
C3 MyCompany
C4 SomeCompany
C5 ZCompany
C6 Company123
C7 ComapnyABC
CompanyActivities
- COMPANYID
中的CompanyActivities
在COMPANYID
(主要密钥表)和{{1}中与CompanyMaster
建立了主键 - foreighkey关系在ACTIVITYID
(主键表)中有ACTIVITYID
的primarykey-foreighkey关系
ActivityMaster
我想编写一个查询来获取以下输出,其中COMPANYID ACTIVITYID
C1 A1
C1 A3
C3 A1
C3 A2
C4 A5
C5 A1
C6 A3
C7 A3
表的ACTIVITYID
列中的所有行都将转换为列
输出
ActivityMaster
输出表将所有公司显示为第一列中的行,并且所有活动都显示为在第一列之后开始的列,如果有行包含Companies A1 A2 A3 A4 A5
C1 Y N Y N N
C2 N N N N N
C3 Y Y N N N
C4 N N N N Y
C5 Y N N N N
C6 N N Y N N
C7 N N Y N N
和ACTIVITYID
的行将在输出中设置为COMPANYID
,否则将设置为Y
例如 - N
COMPANYID
在C1
表中有一个活动ACTIVITYID
A1
,因此第二列中的第一行位于CompanyActivities
下方1}}和A1
的右侧设置为C1
,而Y
和C1
没有行,因此第一行中的第三列设置为A2
我正在使用C#.net和4 for循环来实现输出现在正在对应用程序的性能造成严重影响,所以我想使用查询来执行此操作,我已经搜索了数据透视查询,但是我找到的所有示例都知道前面的列名,我不会通过查询N
来获取列名的名称。
答案 0 :(得分:2)
create table #CompanyMaster (COMPANYID int, COMPANYNAME varchar(30))
create table #ActivityMaster (ACTIVITYID int, ACTIVITYNAME varchar(30))
create table #CompanyActivities (COMPANYID int, ACTIVITYID int)
insert into #CompanyMaster
SELECT 1, 'Company A'
union all
SELECT 2, 'Company B'
insert into #ActivityMaster
SELECT 101, 'Activity X'
union all
SELECT 102, 'Activity Y'
union all
SELECT 103, 'Activity Z'
insert into #CompanyActivities
select 1, 102
union all
select 2, 101
-- build activities column names
--case [Activity X] when 0 then ''N'' else ''Y'' end as [Activity X],
--case [Activity Y] when 0 then ''N'' else ''Y'' end as [Activity Y],
--case [Activity Z] when 0 then ''N'' else ''Y'' end as [Activity Z]
declare @activities nvarchar(max)
set @activities
= (
select 'case [' + ACTIVITYNAME + '] when 0 then ''N'' else ''Y'' end as [' + ACTIVITYNAME + '],' + char(10)
from #ActivityMaster
for xml path('')
)
set @activities = substring(@activities, 0, len(@activities)-1)
declare @activities_for nvarchar(max)
-- build activities column names in for
--[Activity X], [Activity Y], [Activity Z]
set @activities_for
= (
select '[' + ACTIVITYNAME + '],' + char(10)
from #ActivityMaster
for xml path('')
)
set @activities_for = substring(@activities_for, 0, len(@activities_for)-1)
declare @sql nvarchar(MAX) = N'
select COMPANYNAME,
<activities>
From
(select c.COMPANYNAME, a.ACTIVITYNAME,
(case
when ca.ACTIVITYID is not null and ca.COMPANYID is not null then 1
else 0
end) as STATUS
from #CompanyMaster c
cross join #ActivityMaster a
left join #CompanyActivities ca on ca.COMPANYID = c.COMPANYID and a.ACTIVITYID = ca.ACTIVITYID) p
pivot
(
sum(STATUS) for ACTIVITYNAME IN (<activities_for>)
) as pvt
'
set @sql = replace(@sql, '<activities>', @activities)
set @sql = replace(@sql, '<activities_for>', @activities_for)
print @sql
exec sp_executesql @sql
drop table #CompanyMaster
drop table #ActivityMaster
drop table #CompanyActivities