특정 행을 열 이름으로 전송합니다
-
06-09-2019 - |
문제
이 표 1처럼 보이는 몇 개의 테이블이 있습니다.
user_id | name
-------------------------
x111 | Smith, James
x112 | Smith, Jane
등..
표 2
id | code | date | incident_code | user_id
-----------------------------------------------------------------
1 | 102008 | 10/20/2008 | 1 | x111
2 | 113008 | 11/30/2008 | 3 | x111
3 | 102008 | 10/20/2008 | 2 | x112
4 | 113008 | 11/30/2008 | 5 | x112
내가 표시하고 싶은 것은 다음과 같습니다
user_id | user_name | INCIDENT IN OCT 2008 | INCIDENT IN NOV 2008
------------------------------------------------------------------------------
x111 | Smith, John | 1 | 3
x112 | Smith, Jane | 2 | 5
등..
Deasion_code는 다른 테이블에 위치한 사고에 대한 실제 설명으로 대체되지만 이것이 어떻게 먼저 작동하는지 알았습니다.
열 헤더 중 일부는 정적이며 다른 열 헤더는 날짜에 따라 생성됩니다. SQL Server 2005를 사용하여 어떻게 할 수 있는지 아는 사람이 있습니까? 몇 가지 예는 매우 도움이 될 것입니다.
미리 감사드립니다
해결책
다음은 피벗으로 동적 SQL을 생성하고 실행하는 솔루션입니다.
DECLARE @pivot_list AS VARCHAR(MAX)
--
;
WITH cols
AS ( SELECT DISTINCT
'INCIDENT IN ' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)),
3) + ' '
+ SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
FROM so926209_2
)
SELECT @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + col + ']'
FROM cols
--
DECLARE @template AS VARCHAR(MAX)
SET @template = 'WITH incidents AS (
SELECT [user_id],
incident_code,
''INCIDENT IN '' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)), 3)
+ '' '' + SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
FROM so926209_2
)
,results AS (
SELECT * FROM incidents PIVOT (MAX(incident_code) FOR col IN ({@pivot_list})) AS pvt
)
SELECT results.[user_id]
,so926209_1.[name]
,{@select_list}
FROM results INNER JOIN so926209_1 ON so926209_1.[user_id] = results.[user_id]
'
DECLARE @sql AS VARCHAR(MAX)
SET @sql = REPLACE(REPLACE(@template, '{@pivot_list}', @pivot_list), '{@select_list}', @pivot_list)
--PRINT @sql
EXEC (@sql)
어디에 so926209_1
, so926209_2
표 1과 표 2입니다
같은 사람에 대해 한 달에 여러 건의 사건이있는 경우, 예를 들어 처리하는 방법을 보여주지 않습니다. 이 예제는이 달의 마지막 사건만을 취합니다.
다른 팁
이것은보고 작업처럼 들립니다. OLAP, 온라인 이완 처리 처리는 종종 데이터베이스 관점에서 언급되는보고는 "전통적인"데이터베이스 액세스, OLTP (온라인 트랜잭션 처리)와는 상당히 자주 다른 경향이있어 종종 더 큰 기간에 걸친 데이터의 큰 집계로 구성되어 있다는 점에서 매우 자주 다른 경향이 있습니다. 시간의. 상당히 자주, 당신이 찾고있는 집계의 종류.
테트라 누트론이 제안한대로 피벗을 사용하면 더 작은 데이터 세트에 충분할 것입니다. 그러나보고해야 할 데이터의 양이 성장하므로보다 진보 된 것이 필요할 수 있습니다. OLAP는 2005 년과 2008 년에 제공되는 SQL Server Analysis Services (SSAS)에 의해 제공됩니다. SSA를 사용하면 OLTP 데이터베이스 또는 중개자 데이터 창고 데이터베이스에서 데이터를 사전 응집하는 다차원 데이터 리포지토리를 만들 수 있습니다. 다차원 데이터 (일반적으로 큐브라고 함)는 OLTP 데이터베이스에서 표준 트랜잭션 처리의 성능을 방해하지 않고 피벗에서 얻을 수있는 데이터 종류에 액세스 할 수있는 훨씬 빠른 방법을 제공합니다.
보고해야 할 소량 이상의 데이터가있는 경우 SQL Server Analysis Services 2005, OLAP, Cubes 및 MDX (T-SQL의 다차원 확장)를 확인하는 것이 좋습니다. OLAP 큐브를 만들지 만 일단 설정되면 상당한보고 요구가 있으면 하나를 갖는 이점이 크게 될 수 있습니다.
이와 같은 쿼리가 작동합니다.
select
u.User_id,
u.Name,
Okt2008Sum = sum(case when i.date between
'2008-10-01' and '2008-11-01' then 1 else 0 end),
Nov2008Sum = sum(case when i.date between
'2008-11-01' and '2008-12-01'then 1 else 0 end)
from #incidents i
inner join #users u on i.user_id = u.user_id
group by u.user_id, u.name
클라이언트에 따라 얼마나 자주 실행 해야하는지에 따라이 쿼리를 생성 할 수 있습니다. SQL에서 이것은 다음과 같습니다.
create table #months (
MonthName varchar(25),
StartDate datetime
)
insert into #months values ('Okt2008','2008-10-01')
insert into #months values ('Nov2008','2008-11-01')
declare @query varchar(8000)
select @query = 'select u.User_id, u.Name '
select @query = @query + ', ' + MonthName +
' = sum(case when i.date between ''' + cast(StartDate as varchar) +
''' and ''' + cast(dateadd(m,1,StartDate) as varchar) +
''' then 1 else 0 end) '
from #Months
select @query = @query + '
from #incidents i
inner join #users u on i.user_id = u.user_id
group by u.user_id, u.name'
exec (@query)