如果事先知道成绩的数量,那么您可以使用静态查询来完成。
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演示(适用于两种方法)。
更新在 Sql Server 中,您可以使用STUFF
并PIVOT
使用动态 sql 生成预期结果
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演示。