1 题目描述
表: Point
+-------------+------+
| Column Name | Type |
+-------------+------+
| x | int |
+-------------+------+
在 SQL 中, x 是该表的主键列
该表的每一行表示 X 轴上一个点的位置
找到 Point 表中任意两点之间的最短距离
2 测试用例
输入: Point 表:
+----+
| x |
+----+
| -1 |
| 0 |
| 2 |
+----+
输出:
+----------+
| shortest |
+----------+
| 1 |
+----------+
解释: 点-1 和 0 之间的最短距离为|(-1) - 0| = 1
3 解题思路
3.1 解法 1: 使用 abs() 和 min ()
- Point 表外连接自己 p1, p2, 在
p1.x != p2.x的前提下, 计算两者之间差值的绝对值
select p1.x, p2.x,abs(p1.x - p2.x) from Point p1, Point p2 where p1.x != p2.x;
查询结果
+--+--+----------------+
|x |x |abs(p1.x - p2.x)|
+--+--+----------------+
|2 |-1|3 |
|0 |-1|1 |
|2 |0 |2 |
|-1|0 |1 |
|0 |2 |2 |
|-1|2 |3 |
+--+--+----------------+
- 使用
min找出最小值
select min(abs(p1.x - p2.x)) as shortest from Point p1, Point p2 where p1.x != p2.x;
查询结果
+--------+
|shortest|
+--------+
|1 |
+--------+
3.2 解法 2: 使用 lag() 和 over()
- 对数据进行升序排序, 计算当前的行和上一行数据的差值
select x - lag(x) over (order by x) as shortest from Point order by shortest;
查询结果
+--------+
|shortest|
+--------+
|null |
|1 |
|2 |
+--------+
通过分页跳过第一条数据的 null, 获取第二条数据, 就是最小值
select x - lag(x) over (order by x) as shortest from Point order by shortest limit 1, 1;
查询结果
+--------+
|shortest|
+--------+
|1 |
+--------+
此处最开始的想法是通过 min() 获取最小值, 但结果中存在 null, 执行 sql 会报错