forked from leetlab11/Advanced-SQL-50
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path29-00613-shortest-distance-in-a-line.sql
106 lines (80 loc) · 3.24 KB
/
29-00613-shortest-distance-in-a-line.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
613. Shortest Distance in a Line
Table: Point
+-------------+------+
| Column Name | Type |
+-------------+------+
| x | int |
+-------------+------+
In SQL, x is the primary key column for this table.
Each row of this table indicates the position of a point on the X-axis.
Find the shortest distance between any two points from the Point table.
The result format is in the following example.
Example 1:
Input:
Point table:
+----+
| x |
+----+
| -1 |
| 0 |
| 2 |
+----+
Output:
+----------+
| shortest |
+----------+
| 1 |
+----------+
Explanation: The shortest distance is between points -1 and 0 which is |(-1) - 0| = 1.
Follow up: How could you optimize your solution if the Point table is ordered in ascending order?
-- SQL Schema
Create Table If Not Exists Point (x int not null)
Truncate table Point
insert into Point (x) values ('-1')
insert into Point (x) values ('0')
insert into Point (x) values ('2')
-- Solution
----------------------------------------------------------------------------------------------------------------
--Oracle
----------------------------------------------------------------------------------------------------------------
-- 1. using Lead funtion
select min(diff) shortest
from(
select lead(x) over(order by x) -x diff
from Point
)
-- 2. using CTE and ABS function
----------------------------------------------------------------------------------------------------------------
-- MySQL
----------------------------------------------------------------------------------------------------------------
-- cross joining all the points from 2 tables, except the ones where they are same
-- find the min of absolute distance
select min(abs(a - b)) as shortest
from
(select p1.x as a, p2.x as b
from Point p1 cross join Point p2
where p1.x != p2.x) temp
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- concise version of the above
select min(abs(p1.x - p2.x)) as shortest
from Point p1 cross join Point p2
where p1.x != p2.x
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- pull min distance with a where condition
select min(p1.x - p2.x) as shortest
from Point p1, Point p2
where p1.x > p2.x
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- sort the table, and do lag. Now diff between current and lag- because difference between the sorted will always be lesser than difference between the larger ones
-- pull the min distance
with CTE as
(select x - lag(x) over(order by x) as distance
from Point)
select min(distance) as shortest from CTE
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- picking the lowest distance, 1st row will always be null hence use offset
select x - lag(x) over(order by x) as shortest
from Point
order by 1 asc
limit 1 offset 1
-- no companies listed