0

私は2つのテーブルを持っています。それらは次のとおりです

表:グレード

GradeID | Grade 
----------------- 
1       | Chopsaw  
2       | Classic
3       | Chieve

表:成形量

Batch ID | Grade | Moulded | Date 
-------------------------------------
1        | 1     | 150     | 21st May
2        | 1     | 150     | 22nd May
3        | 2     | 150     | 21st May
4        | 2     | 150     | 21st May
5        | 2     | 150     | 22nd May

次のような出力を取得する必要があります

Date       | Moulded  | Chopsaw | Classic | Cieve   
--------------------------------------------------
21st May   | 450      | 150     | 300     | 0    
22nd May   | 300      | 150     | 150     | 0

私は MSSQL 2008 を使用しており、Crystal レポートを使用して同じものを表示しています。

4

2 に答える 2

3

成績の数が事前にわかっている場合は、静的クエリを使用して行うことができます。

SELECT date,
       SUM(moulded) moulded,
       SUM(CASE WHEN grade = 1 THEN moulded ELSE 0 END) Chopsaw,
       SUM(CASE WHEN grade = 2 THEN moulded ELSE 0 END) Classic,
       SUM(CASE WHEN grade = 3 THEN moulded ELSE 0 END) Chieve
  FROM moulded_quantity 
 GROUP BY date

このクエリはベンダー固有ではないため、主要な RDBMS で動作するはずです。

現在、グレードの数が不明な場合、またはgradeテーブルに変更を加えても (クエリ自体を変更せずに) 動作させたい場合は、動的クエリに頼ることができます。ただし、動的 ​​SQL はベンダー固有です。MySqlでそれを行う方法の例を次に示します

SELECT CONCAT (
        'SELECT date, SUM(moulded) moulded,',
        GROUP_CONCAT(DISTINCT
        CONCAT('SUM(CASE WHEN grade = ',gradeid,
               ' THEN moulded ELSE 0 END) ', grade)),
        ' FROM moulded_quantity GROUP BY date') INTO @sql
FROM grade;

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

出力 (両方の場合):

| | 日付 | 成形 | チョップソー | クラシック | チーブ |
-------------------------------------------------- -
| | 5月21日 | 450 | 150 | 300 | 0 |
| | 5月22日 | 300 | 150 | 150 | 0 |

SQLFiddleデモ (両方のアプローチ) を次に示します。

UPDATE Sql Serverでは、動的SQLで期待される結果を生成するためにSTUFF使用できますPIVOT

DECLARE @colx NVARCHAR(MAX), @colp NVARCHAR(MAX), @sql NVARCHAR(MAX)

SET @colx = STUFF((SELECT ', ISNULL(' + QUOTENAME(Grade) + ',0) ' + QUOTENAME(Grade)
            FROM grade
            ORDER BY GradeID
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'),1,1,'')

SET @colp = STUFF((SELECT DISTINCT ',' + QUOTENAME(Grade)
            FROM grade
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'),1,1,'')

SET @sql = 'SELECT date, total moulded, ' + @colx +   
           '  FROM 
            (
              SELECT date, g.grade gradename, moulded,
                     SUM(moulded) OVER (PARTITION BY date) total
                FROM moulded_quantity q JOIN grade g
                  ON q.grade = g.gradeid
            ) x
            PIVOT 
            (
               SUM(moulded) FOR gradename IN (' + @colp + ')
            ) p
            ORDER BY date'

EXECUTE(@sql)

出力は MySql の場合と同じです。

これがSQLFiddle のデモです。

于 2013-06-17T07:35:49.707 に答える
0

非常に一般的な質問であるため、質問をする前に最初に調査することをお勧めします。

更新しました

DECLARE @COLUMNS varchar(max) 
SELECT @COLUMNS = COALESCE(@COLUMNS+'],[' ,'') +  CAST(Grade as varchar)
FROM Grade
GROUP BY Grade


SET @COLUMNS = '[' + @COLUMNS + ']'


DECLARE @COLUMNS_WITH_NULL varchar(max) 
SELECT @COLUMNS_WITH_NULL  = COALESCE(@COLUMNS_WITH_NULL+',ISNULL([' ,'ISNULL([') +  CAST(Grade as varchar) + '], 0) AS ' +  CAST(Grade as varchar) 
FROM Grade
GROUP BY Grade

DECLARE @COLUMNS_SUMS varchar(max) 
SELECT @COLUMNS_SUMS  = COALESCE(@COLUMNS_SUMS+' + ISNULL([' ,'ISNULL([') +  CAST(Grade as varchar) + '], 0) ' 
FROM Grade
GROUP BY Grade


SET @COLUMNS_SUMS = '(' + @COLUMNS_SUMS + ') as Moulded'
PRINT @COLUMNS_SUMS


EXECUTE (
'
SELECT 
    Date, ' + @COLUMNS_SUMS + ', ' +  @COLUMNS_WITH_NULL + '
FROM (

SELECT 
    m.Moulded,
    m.date AS Date,
    g.Grade
FROM Grade g
INNER JOIN [Moulded Quantity] m
ON m.GRADE = g.GradeID
) up
PIVOT (SUM(Moulded) FOR  Grade IN ('+ @COLUMNS +')) AS pvt')
于 2013-06-17T09:46:31.640 に答える