# SQL面试题：行列如何互换？

**URL:** <https://www.shiqidu.com/t/topic/609>\
**Category:** 开发调优\
**Tags:** MySQL\
**Created:** [2019 年7 月 26 日 16:13 UTC](https://www.shiqidu.com/t/topic/609 "2019-07-26T16:13:29Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![yeqiu](https://www.shiqidu.com/user_avatar/www.shiqidu.com/yeqiu/32/14_2.png) [@yeqiu](https://www.shiqidu.com/u/yeqiu)\
发布日期： [2019 年7 月 26 日 16:13 UTC](https://www.shiqidu.com/t/topic/609/1 "2019-07-26T16:13:29Z")

</div>

【面试题】下面是学生的成绩表（表名score，列名：学号、课程号、成绩）

 ![](https://discourse.shiqidu.com/uploads/default/original/1X/72289d5ee82fff911007ab16fd1211c3e16447c2.jpeg)

使用sql实现将该表行转列为下面的表结构

 ![](https://discourse.shiqidu.com/uploads/default/original/1X/8829c78a348ebe52c4a2237ff1eeecbb9c71b0d4.jpeg)

【解答】

### 第1步，使用常量列输出目标表的结构

可以看到查询结果已经和目标表非常接近了

```sql
select 学号,'课程号0001','课程号0002','课程号0003'from score;

```

 ![](https://discourse.shiqidu.com/uploads/default/original/1X/5c6e28f48d9a66f031c4545ca863f10e19055d71.jpeg)

### 第2步，使用case表达式，替换常量列为对应的成绩

```sql
select 学号,(case 课程号 when '0001' then 成绩 else 0 end) as '课程号0001',(case 课程号 when '0002' then 成绩 else 0 end) as '课程号0002',(case 课程号 when '0003' then 成绩 else 0 end) as '课程号0003'from score;

```

 ![](https://discourse.shiqidu.com/uploads/default/original/1X/ff18706d118eb414ebfac7417e7547eb52855e35.png)

在这个查询结果中，每一行表示了某个学生某一门课程的成绩。比如第一行是’学号0001’选修’课程号00001’的成绩，而其他两列的’课程号0002’和’课程号0003’成绩为0。

每个学生选修某门课程的成绩在下图的每个方块内。我们可以通过分组，取出每门课程的成绩。

 ![](https://discourse.shiqidu.com/uploads/default/original/1X/11a211770f904b43554c313fd9ec812c950825ad.png)

### 第3关，分组

分组，并使用最大值函数max取出上图每个方块里的最大值

```sql
select 学号,max(case 课程号 when '0001' then 成绩 else 0 end) as '课程号0001',max(case 课程号 when '0002' then 成绩 else 0 end) as '课程号0002',max(case 课程号 when '0003' then 成绩 else 0 end) as '课程号0003'from scoregroup by 学号;

```

这样我们就得到了目标表（行列互换）

![](https://discourse.shiqidu.com/uploads/default/original/1X/f63ad9742a9925dcb56914d6330cdd25ae27cfb1.png)
