题目描述

(通过次数12,255 | 提交次数18,744,通过率65.38%)

Point2D 表:
+-------------+------+
| Column Name | Type |
+-------------+------+
| x           | int  |
| y           | int  |
+-------------+------+
(x, y) 是这张表的主键
这张表的每一行表示 X-Y 平面上一个点的位置

p1(x1, y1) 和 p2(x2, y2) 这两点之间的距离是 sqrt((x2 - x1)2 + (y2 - y1)2) 。
请你写一个 SQL 查询报告 Point2D 表中任意两点之间的最短距离。保留 2 位小数 。
查询结果格式如下例所示。

示例:
输入:
Point2D table:
+----+----+
| x  | y  |
+----+----+
| -1 | -1 |
| 0  | 0  |
| -1 | -2 |
+----+----+
输出:
+----------+
| shortest |
+----------+
| 1.00     |
+----------+
解释:最短距离是 1.00 ,从点 (-1, -1) 到点 (-1, 2) 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shortest-distance-in-a-plane
--测试数据
Create Table If Not Exists Point2D (x int not null, y int not null);

insert into Point2D (x, y) values ('-1', '-1');
insert into Point2D (x, y) values ('0', '0');
insert into Point2D (x, y) values ('-1', '-2');

解题思路

这道题主要是考查SQL编程中,对函数的综合运用。

根据题目要求,已知一组点的坐标(x,y),需要计算出所有点之间的最短距离。

那么,一般来说,我们可以计算出任意两点之间的距离,然后取一个最小值即可。

因为源表Point2D保留的是一个个孤立的点, 在计算两两之间的距离时,需要所有点之间的关系的排列组合。提到排序组合,我们知道,可以使用笛卡尔积来实现。

但笛卡尔积本身返回的结果,是包含自身与自身的关系的,这一类关系需要剔除。

因此,使用下面的语句,可以获取所有点的两两组合,且不包括自身与自身的组合。

select
    a.x,a.y,b.x,b.y
from Point2D a
inner join Point2D b
on a.x != b.x
or a.y != b.y;

有了以上组合,我们就可以根据公式计算出所有点之间的距离:

p1(x1, y1) 和 p2(x2, y2)之间的距离:sqrt((x2 – x1)2 + (y2 – y1)2)

从上面公式来看,我们需要平方的函数pow,还需要取根号的函数sqrt。因为最后结果需要保留2位小数,所以还需要round函数。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select
    min(round(sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2)),2)) shortest
from Point2D a
inner join Point2D b
on a.x != b.x
or a.y != b.y;
picture loss