成績の数が事前にわかっている場合は、静的クエリを使用して行うことができます。
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 のデモです。