列名に特定の行を転置クエリ
-
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
など。
incident_codeは、別のテーブル内に配置されている事件の実際の記述で置き換えることであろうが、私は、これが最初に動作する方法を見ると思った。
他の人が日付に基づいて作成されるでしょうが、列ヘッダーのいくつかは、静的になります。 誰一つは、私はSQL Server 2005を使用してこれを行うことができます方法を知っていますか?いくつかの例としては、非常に参考になります。
事前に感謝します。
解決
ここで生成し、PIVOTと、動的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である場合、
あなたは同じ人のために月に複数の事件を持っている場合、あなたの例を扱うことをあなたが望む方法を示していないことに注意してください。この例は、月の最後の事件をとります。
他のヒント
あなたは旋回するようにしたいです http://msdn.microsoft.com/en-us/library/ms177410。 ASPXする
これは、レポートタスクのように聞こえます。多くの場合、OLAP、オンラインAanalytical処理として、データベースの視点から参照、レポーティング、それはかなり頻繁に大きい期間にまたがるデータの大規模な集合体で構成されている中で、「伝統的な」データベース・アクセス、OLTP(オンライントランザクション処理)からかなり頻繁に異なる傾向時間の。かなり頻繁に、集約の種類は、あなたを探しています。
テトラニュートロンは、小さなデータセットのために十分であろう示唆されるようにピボットの使用。しかし、あなたが成長する上で報告する必要があるデータの量として、あなたは、より高度なものが必要な場合があります。 OLAPは、あなたがその直接、または中間のデータウェアハウスデータベースからOLTPデータベースのいずれかから事前集計データの多次元データリポジトリを作成することができますSSASを使用して2005年と2008年に、SQL Serverの分析サービス(SSAS)によってのために利用可能に提供されます。多次元データ(通常はキューブと呼ばれる)は、あなたがあなたのOLTPデータベースでの標準のトランザクション処理のパフォーマンスに干渉することなく、ピボットから取得できるデータの種類にアクセスするためのはるかに高速な方法を提供します。
あなたはあなたが報告する必要が少量のデータが複数ある場合は、、私はあなたがSQL ServerのAnalysis Servicesの2005年、OLAP、キューブ、およびMDXチェックアウトをお勧めします(T-SQLのための多次元拡張を。)拡大learnigがあります曲線はOLAPキューブを設定するには、それが設定されると、あなたは重要なレポートのニーズを持っている場合、1つを有することの利点は巨大なことができます。
このようなクエリは動作します。
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)