2

以下のようにテーブルを設定しています。

CLIENTNAME MONTHANDYEAR RESOURCE COST
abc JAN2011 res1 1000
abc FEB2011 res1 2000
def JAN2011 res2 1500
def MAR2011 res1 2000
ghi MAR2011 res3 2500

以下のような出力が必要です。月は 3 か月間隔で動的に生成されます。この場合、クライアント名でグループ化するだけでなく、MONTHANDYEAR でピボットする方法はありますか?

リソース クライアント名 JAN2011 FEB2011 MAR2011   
res1 abc 1000 1000
res1 デフ 2000
res2 デフ 1500
res3 ギ 2500
4

3 に答える 3

3

これが PIVOT 演算子の目的です。

SELECT 
  Resource, ClientName,
  [JAN2011], [FEB2011], [MAR2011]
FROM
  (
  SELECT 
    *  
  FROM tblname
  ) AS SourceTable
PIVOT
  (
  SUM(COST)
  FOR MONTHANDYEAR IN ([JAN2011], [FEB2011], [MAR2011])
  ) AS PivotTable;

月は @startDate を基準月として動的に選択されるため、次の動的クエリを使用できます。

DECLARE @startDate datetime
SET @startDate = '2011-01-01'

DECLARE @sql varchar(MAX)
SET @sql = 'SELECT
        Resource, ClientName, [' +
          REPLACE(SUBSTRING(CONVERT(varchar, @startDate, 13), 4, 8), ' ', '') + '], [' +
          REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 1, @startDate), 13), 4, 8), ' ', '') + '], [' +
          REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 2, @startDate), 13), 4, 8), ' ', '') + ']
        FROM
          (
          SELECT
            *
          FROM tblName
          ) AS SourceTable
        PIVOT
          (
          SUM(COST)
          FOR MONTHANDYEAR IN (' +
                  QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, @startDate, 13), 4, 8), ' ', '')) + ', ' +
                  QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 1, @startDate), 13), 4, 8), ' ', '')) + ', ' +
                  QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 2, @startDate), 13), 4, 8), ' ', '')) + ')
          ) AS PivotTable'

execute(@sql)

ここで作業中のsqlfiddle

于 2013-02-22T04:32:50.960 に答える
1

このデータ変換は、PIVOT関数を使用して実行できます。

値がわかっている場合は、monthandyear日付をハードコーディングできます。

select resource,
  clientname,
  isnull(jan2011, '') Jan2011,
  isnull(feb2011, '') Feb2011,
  isnull(mar2011, '') Mar2011
from
(
  select clientname, monthandyear, resource, cost
  from yourtable
) src
pivot
(
  sum(cost)
  for monthandyear in (Jan2011, Feb2011, Mar2011)
) piv;

SQL Fiddle with Demoを参照してください。

ただし、日付が不明な場合は、動的 SQL を使用する必要があります。

DECLARE @cols AS NVARCHAR(MAX),
    @colNames AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(monthandyear) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colNames = STUFF((SELECT distinct ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear)
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT resource, clientname,' + @colNames + ' from 
             (
                select clientname, monthandyear, resource, cost
                from yourtable
            ) x
            pivot 
            (
                sum(cost)
                for monthandyear in (' + @cols + ')
            ) p '

execute(@query)

SQL Fiddle with Demoを参照してください。

両方の結果は次のとおりです。

| RESOURCE | CLIENTNAME | JAN2011 | FEB2011 | MAR2011 |
-------------------------------------------------------
|     res1 |        abc |    1000 |    2000 |       0 |
|     res1 |        def |       0 |       0 |    2000 |
|     res2 |        def |    1500 |       0 |       0 |
|     res3 |        ghi |       0 |       0 |    2500 |
于 2013-02-22T12:46:39.107 に答える
0
SELECT Resource, Clientname
, SUM(CASE WHEN MonthAndYear = 'JAN2011' THEN COST ELSE 0 END) AS JAN2011
, SUM(CASE WHEN MonthAndYear = 'FEB2011' THEN COST ELSE 0 END) AS FEB2011
, SUM(CASE WHEN MonthAndYear = 'MAR2011' THEN COST ELSE 0 END) AS MAR2011
FROM yourtable
GROUP BY Resource, Clientname

を削除して、データなしのリソース/クライアント名の組み合わせELSE 0の値を返すこともできますNULL

于 2013-02-22T04:26:36.530 に答える