Запрос T-SQL для преобразования строк в кумны на основе нескольких таблиц - PullRequest
2 голосов
/ 19 октября 2011

У меня есть две основные таблицы 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 в CompanyMaster (таблица первичных ключей), а ACTIVITYID имеет корабль отношения первичный ключ-ключ с ACTIVITYID в 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 таблице, поэтому первая строка во втором столбце, которая находится чуть ниже A1 и справа C1установлен Y, тогда как C1 и A2 не имеют строки, поэтому третий столбец в первой строке установлен на N

Я использую C # .net и 4 для цикловчтобы сейчас получить результат, который говорит о значительном снижении производительности приложения, поэтому я хотел бы сделать это с помощью запроса, я искал сводные запросы, но все примеры, которые я нашел, заранее знают имена столбцов,что я не знаю, я получаю имена столбцов только путем запроса ActivityMaster.

1 Ответ

2 голосов
/ 19 октября 2011
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...