题目描述

(通过次数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
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
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');
--测试数据 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');
--测试数据
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;
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;
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;
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;
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