1

ピボット SQL を作成しましたが、動作しています。現在の SQL ステートメントを以下に示します。データがどのように返されるかの例を示します。列を 1 つ追加する必要があり、これが爆発する場所です。

Select 
    ProductGroup,
    Origin,
    Destination,
    [YEAR], 
    Isnull([Jan],0) as "Jan",
    isnull([Feb],0) as "Feb",
    isnull([Mar],0) as "Mar",
    isnull([Apr],0) as "Apr",
    isnull([May],0) as "May",
    isnull([Jun],0) as "Jun",
    isnull([Jul],0) as "Jul",
    isnull([Aug],0) as "Aug",
    isnull([Sep],0) as "Sep",
    isnull([Oct],0) as "Oct",
    isnull([Nov],0) as "Nov",
    isnull([Dec],0) as "Dec"
FROM
(
SELECT 
    p.ProductGroup, 
    S.Origin, 
    S.FinalDest AS Destination,
    SUBSTRING('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec', (Month(boldate) * 4) - 3, 3) as MonthAbreviated, 
    Year(BolDate) AS [Year], 
    Count(*) AS [Total]
--  ,COUNT(S.Purchase#) AS [TheTotal]
    FROM 
        dbo.Contracts c INNER JOIN dbo.Purchases pu ON c.[Contract#] = pu.[Contract#]
        INNER JOIN dbo.Products as p ON pu.Product = p.Product 
        INNER JOIN dbo.Shipments S ON pu.[Purchase#] = S.[Purchase#]
WHERE 
    Year(BolDate)<>1994 AND
    pu.Cancelled=0 AND S.[Status]='L'
GROUP BY p.ProductGroup, S.Origin, S.FinalDest,Year(BolDate), SUBSTRING('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec', (Month(boldate) * 4) - 3, 3)

) AS SourceTable
PIVOT
(
sum( Total )
FOR MonthAbreviated IN ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec])
) AS PivotTable

結果の例:

ProductGroup   Origin  Destination  YEAR        Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 
Nail           Bath    Toronto      2012        0   0   0   10  1   0   0   0   0   0   0   0 
Nail           Cedars  Toronto      2011        0   0   0   0   0   0   0   0   0   0   25  53

行の合計を表示する列を追加する必要があります。たとえば、行 1 は 11 で、行 2 は 78 です。私の選択では、クエリに「合計」を追加するだけで済むと思いましたが、毎回無効な列が表示されます。

つまり、次のエラーが表示されます。

メッセージ 207、レベル 16、状態 1、行 6 列名「合計」が無効です。

Select 
    ProductGroup,
    Origin,
    Destination,
    [YEAR], 
    [Total],
    Isnull([Jan],0) as "Jan",
    isnull([Feb],0) as "Feb",
    isnull([Mar],0) as "Mar",
    isnull([Apr],0) as "Apr",
    isnull([May],0) as "May",
    isnull([Jun],0) as "Jun",
    isnull([Jul],0) as "Jul",
    isnull([Aug],0) as "Aug",
    isnull([Sep],0) as "Sep",
    isnull([Oct],0) as "Oct",
    isnull([Nov],0) as "Nov",
    isnull([Dec],0) as "Dec"
FROM
(
SELECT 
    p.ProductGroup, 
    S.Origin, 
    S.FinalDest AS Destination,
    SUBSTRING('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec', (Month(boldate) * 4) - 3, 3) as MonthAbreviated, 
    Year(BolDate) AS [Year], 
    Count(*) AS [Total]
--  ,COUNT(S.Purchase#) AS [TheTotal]
    FROM 
        dbo.Contracts c INNER JOIN dbo.Purchases pu ON c.[Contract#] = pu.[Contract#]
        INNER JOIN dbo.Products as p ON pu.Product = p.Product 
        INNER JOIN dbo.Shipments S ON pu.[Purchase#] = S.[Purchase#]
WHERE 
    Year(BolDate)<>1994 AND
    pu.Cancelled=0 AND S.[Status]='L'
GROUP BY p.ProductGroup, S.Origin, S.FinalDest,Year(BolDate), SUBSTRING('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec', (Month(boldate) * 4) - 3, 3)

) AS SourceTable
PIVOT
(
sum( Total )
FOR MonthAbreviated IN ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec])
) AS PivotTable
4

2 に答える 2

1

代わりにROLLUPを使用することもできます

あなたがする必要があります

  • ケースステートメントを追加して、ロールアップに「名前」を付けます

     CASE WHEN (GROUPING(Substring(DateName(m,boldate),1,3) = 1) Then 'Total'
          ELSE Substring(DateName(m,boldate),1,3) 
     END as MonthAbreviated, 
    
  • グループにRollUpを追加する

     GROUP BY
      ....
      Substring(DateName(m,boldate),1,3) 
      WITH ROLLUP
    
  • FOR句に含めます

     ... [Nov],[Dec], [Total])
    
  • 持つ他のすべてのロールアップ グループを除外します。

          HAVING
             GROUPING (Year(BolDate) = 0)
    

MonthAbreviated 構文を変更して短くしたことに注意してください。ピボットされた値と同じ名前だったため、Count(*) のエイリアスを変更する必要がありました。

Select 
    ProductGroup,
    Origin,
    Destination,
    [YEAR], 
    Isnull([Jan],0) as "Jan",
    isnull([Feb],0) as "Feb",
    isnull([Mar],0) as "Mar",
    isnull([Apr],0) as "Apr",
    isnull([May],0) as "May",
    isnull([Jun],0) as "Jun",
    isnull([Jul],0) as "Jul",
    isnull([Aug],0) as "Aug",
    isnull([Sep],0) as "Sep",
    isnull([Oct],0) as "Oct",
    isnull([Nov],0) as "Nov",
    isnull([Dec],0) as "Dec",
    isnull([Total],0) as "Total"
FROM
(
SELECT 
    p.ProductGroup, 
    S.Origin, 
    S.FinalDest AS Destination,
    CASE WHEN (GROUPING(Substring(DateName(m,boldate),1,3) = 1) Then 'Total'
         ELSE Substring(DateName(m,boldate),1,3) 
    END as MonthAbreviated, 
    Year(BolDate) AS [Year], 
    Count(*) AS [Kount]
    FROM 
        dbo.Contracts c INNER JOIN dbo.Purchases pu ON c.[Contract#] = pu.[Contract#]
        INNER JOIN dbo.Products as p ON pu.Product = p.Product 
        INNER JOIN dbo.Shipments S ON pu.[Purchase#] = S.[Purchase#]
WHERE 
    Year(BolDate)<>1994 AND
    pu.Cancelled=0 AND S.[Status]='L'
GROUP BY 
     p.ProductGroup, 
     S.Origin, 
     S.FinalDest,Year(BolDate), 
     Substring(DateName(m,boldate),1,3) 
     WITH ROLLUP
HAVING
    GROUPING (Year(BolDate) = 0)
    

) AS SourceTable
PIVOT
(
sum( Kount )
FOR MonthAbreviated IN ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec], [Total])
) AS PivotTable

これは、data.se でのこの手法のデモです。

于 2012-06-21T15:19:05.867 に答える
1

行の合計が必要な場合は、単純に列を合計して合計を取得できます。したがって、次の行を追加する必要があります。

([Jan] + [Feb] + [Mar] + [Apr] + [May] + [Jun] + [Jul] + [Aug] + [Sep] + [Oct] + [Nov] + [Dec]) as Total

あなたのクエリを作る:

Select 
    ProductGroup,
    Origin,
    Destination,
    [YEAR], 
    Isnull([Jan],0) as "Jan",
    isnull([Feb],0) as "Feb",
    isnull([Mar],0) as "Mar",
    isnull([Apr],0) as "Apr",
    isnull([May],0) as "May",
    isnull([Jun],0) as "Jun",
    isnull([Jul],0) as "Jul",
    isnull([Aug],0) as "Aug",
    isnull([Sep],0) as "Sep",
    isnull([Oct],0) as "Oct",
    isnull([Nov],0) as "Nov",
    isnull([Dec],0) as "Dec",
    ([Jan] + [Feb] + [Mar] + [Apr] + [May] + [Jun] + [Jul] + [Aug] + [Sep] + [Oct] + [Nov] + [Dec]) as Total
FROM
(
SELECT 
    p.ProductGroup, 
    S.Origin, 
    S.FinalDest AS Destination,
    SUBSTRING('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec', (Month(boldate) * 4) - 3, 3) as MonthAbreviated, 
    Year(BolDate) AS [Year], 
    Count(*) AS [Total]
--  ,COUNT(S.Purchase#) AS [TheTotal]
    FROM 
        dbo.Contracts c INNER JOIN dbo.Purchases pu ON c.[Contract#] = pu.[Contract#]
        INNER JOIN dbo.Products as p ON pu.Product = p.Product 
        INNER JOIN dbo.Shipments S ON pu.[Purchase#] = S.[Purchase#]
WHERE 
    Year(BolDate)<>1994 AND
    pu.Cancelled=0 AND S.[Status]='L'
GROUP BY p.ProductGroup, S.Origin, S.FinalDest,Year(BolDate), SUBSTRING('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec', (Month(boldate) * 4) - 3, 3)

) AS SourceTable
PIVOT
(
sum( Total )
FOR MonthAbreviated IN ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec])
) AS PivotTable
于 2012-06-21T14:22:46.950 に答える