使用 PIVOT 的 SQL 查询

Posted

技术标签:

【中文标题】使用 PIVOT 的 SQL 查询【英文标题】:SQL query with PIVOT 【发布时间】:2021-12-25 08:05:36 【问题描述】:

数据:

CREATE TABLE [dbo].[Grade_Report](
    [Student] [varchar](50) NULL,
    [Subject] [varchar](50) NULL,
    [Grades] [numeric](18, 2) NULL,
    [Semester] [int] NULL
);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'Mathematics', CAST(82.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'Science', CAST(83.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'Programming', CAST(91.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'History', CAST(89.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'English', CAST(95.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'Mathematics', CAST(79.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'Science', CAST(80.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'Programming', CAST(92.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'History', CAST(95.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jamie', N'English', CAST(93.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'Mathematics', CAST(95.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'Science', CAST(95.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'Programming', CAST(90.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'History', CAST(92.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'English', CAST(96.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'Mathematics', CAST(78.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'Science', CAST(79.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'Programming', CAST(82.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'History', CAST(80.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jenny', N'English', CAST(79.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'Mathematics', CAST(96.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'Science', CAST(92.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'Programming', CAST(93.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'History', CAST(88.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'English', CAST(94.00 AS Numeric(18, 2)), 1);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'Mathematics', CAST(90.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'Science', CAST(92.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'Programming', CAST(98.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'History', CAST(93.00 AS Numeric(18, 2)), 2);
INSERT [dbo].[Grade_Report] ([Student], [Subject], [Grades], [Semester]) VALUES (N'Jerome', N'English', CAST(90.00 AS Numeric(18, 2)), 2);


SELECT * FROM Grade_Report;

查询:

SELECT Student, [English], [Mathematics], [Science], [Programming], [History]
FROM
(
    SELECT Grades, Subject FROM Grade_Report
)AS SourceTable
PIVOT
(
    AVG(Grades)
    FOR Subject IN([English], [Mathematics], [Science], [Programming], [History])
)AS PivotTable;

Student 突出显示为无效的列名,当我从查询中删除 Student 并执行时,输出如下:

我尝试在查询中以任何方式输入和输出学生列,但它给出了错误。我想要的输出是将科目显示为列,并显示两个学期学生的计算平均成绩。像这样:

【问题讨论】:

您是否尝试在SourceTable 查询的选定列中包含Student?在pivot 操作中,枢轴列需要围绕某些东西进行旋转,在这种情况下,就是您的Student 值。 【参考方案1】:

将学生的姓名放在子查询中 从 ( 从 Grade_Report 中选择 学生、 成绩、科目 )AS SourceTable

SELECT Student, [English], [Mathematics], [Science], [Programming], 
[History]
FROM
(
    SELECT Student, Grades, Subject FROM Grade_Report
)AS SourceTable
PIVOT
(
    AVG(Grades)
    FOR Subject IN([English], [Mathematics], [Science], [Programming], 
    [History])
)AS PivotTable;

【讨论】:

以上是关于使用 PIVOT 的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Fundamentals: 子查询 || 行列转换(PIVOT,UNPIVOT,DECODE),设置数据层次(LEVEL...CONNECT BY)

sql SQL Pivot查询示例。

获取 ROWS 作为 COLUMNS(SQL Server 动态 PIVOT 查询)

SQL 查询两个 PIVOT 列组合

Oracle SQL group by 查询,一种 PIVOT [重复]

SQL Server 动态 PIVOT 查询 - 字段顺序