# 图解面试题：如何交换数据？

![](/files/-MUsThH1iz9oIrOjR-qa)

**【题目】**

小明是一所学校的老师，她有一张 “学生表”，平时用来存放座位号和学生的信息。其中，座位号是连续递增的。总的座位数是偶数。

![](/files/-MUsTorXNF85lkTXkpc6)

现在，小明想改变相邻俩学生的座位。你能不能帮她写一个 sql 查来输出想要的结果呢？

示例查询结果如下：

![](/files/-MUsTsw2VGT7MXkLrqLQ)

**【解题思路】**

**第一步：理清换座位的逻辑**

查询目的是改变相邻学生的座位号。为了理清逻辑，在原表中插入一列叫做“奇偶数”，对应表示 “座位号” 的值是 “奇数” 还是“偶数”。

![](/files/-MUsU-GkLaKDtsG1aG6s)

然后比较原始表里的 “座位号” 和交换结果里的“座位号”（[对比分析方法](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649246563\&idx=2\&sn=3ffe509999d144d23dec5acc101fc2ef\&chksm=835fc353b4284a45ce01391453fe2fec1b225bbd6bbdb67dd7f304aacdd4f21f60d0b27ba309\&scene=21#wechat_redirect)），可以发现下图的规律。

![](/files/-MUsU3Lt6FpQmTafQzec)

1）如果原来座位号是**奇数**的学生，换座位后，这名学生的座位号变为 “座位号 + 1”**。**

2）如果原来座位号是**偶数**的学生，换座位后，这名学生的座位号变为 “座位号 - 1”**。**

**第二步：如何判断座位号是奇数，还是偶数**

sql 求余函数：mod(n,m) ，返回 n 除以 m 的余数。比如 mod(8,2) 的结果是 0。

如果 n 除以 2 的余数是 0，说明 n 是偶数，否则是奇数。

转换为判断奇数，偶数的 sql 就是：

```sql
case
      when mod(座位号, 2) != 0  then  '奇数'
      when mod(座位号, 2)  = 0  then  '偶数'
end
```

把前面的逻辑写到 sql 里就是：

1）如果原来座位号是**奇数**的学生，换座位后，这名学生的座位号变为 “座位号 + 1”**。**

2）如果原来座位号是**偶数**的学生，换座位后，这名学生的座位号变为 “座位号 - 1”**。**

```sql
case
       when mod(座位号, 2) != 0  then 座位号 + 1
       when mod(座位号, 2)  = 0  then 座位号 - 1
end  as  '交换后座位号'
```

加入 select 字句，就是最好的结果：

```sql
select
      (case
             when mod(座位号, 2) != 0  then 座位号 + 1
             when mod(座位号, 2)  = 0  then 座位号 - 1
      end)  as  '交换后座位号',
      姓名
from 学生表;
```

**【本题考点】**

1. 逻辑思维能力，如何使用对比分析方法发现规律
2. 条件判断语句 case
3. 如何判断奇数和偶数：mod 函数

**【举一反三】**

原始座次表 ‘seat’如下，现需要更换相邻位置学生的座次。

注：该座次表‘seat’共有 5 名学生，第 5 个 座位号是奇数的不变

![](/files/-MUsUBcGaEtwL2Zdj1tH)

查询逻辑和前面一样，但是座位总数是奇数，所以：如果最后一个座位号也是奇数，那么他没有可以交换的座位了，所以最后一个座位号的学生不变。

最后一个座位号，等于表里有多少行，可以用 count(\*) 计算出来

```sql
# 最后一个座位号
select count(*) as counts 
from seat;
```

最后一个座位号作为条件判断使用时，可以使用子查询，以便调用。最终 sql 如下。

```sql
select
    (case
      # 当座位号是奇数并且不是不是最后一个座位号时
        when mod(id, 2) != 0 and counts!= id then id + 1
       # 当座位号是奇数并且是最后一个座位号时，座位号不变
        when mod(id, 2) != 0 and counts = id then id
       # 当座位号是偶数时
        else id - 1
    end) as id2,student
from seat,(select count(*) as counts from seat);
```

推荐：[如何从零学会 sql？](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649247566\&idx=2\&sn=5af748b677eb72028764dde0577675fb\&chksm=835fc77eb4284e68e8cfe3f08c5a671b9e080b2651f20b40b1c793ffda4042ae43ad8f35a755\&scene=21#wechat_redirect)

![](/files/-MUsUxrOfWUjk_0YTCxb)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://houzidata.gitbook.io/sql/di-3-zhang-duo-biao-cha-xun/tu-jie-mian-shi-ti-ru-he-jiao-huan-shu-ju.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
