来源:https://leetcode-cn.com/problems/shortest-distance-in-a-l.ne/ & https://leetcode-cn.com/problems/bank-account-summary-ii/ 【侵删修改】
ExampleA:【直线上的最近距离】
表 point
保存了一些点在 x 轴上的坐标,这些坐标都是整数。
写一个查询语句,找到这些点中最近两个点之间的距离。
| x |
|-----|
| -1 |
| 0 |
| 2 |
最近距离显然是 '1' ,是点 '-1' 和 '0' 之间的距离。所以输出应该如下:
| shortest|
|---------|
| 1 |
注意:每个点都与其他点坐标不同,表 table
不会有重复坐标出现。
解题思路(遇到这种一个表查询的问题:上来就直接自己join自己【当然其他最基础的查询不要这么干】 剩余的问题,单独再去考虑)
select min(abs(p1.x-p2.x)) shortest from point p1 inner join point p2 on p1.x != p2.x;
ExampleB:【银行账户概要 II】
表: Users
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| account | int |
| name | varchar |
+--------------+---------+
account 是该表的主键.
表中的每一行包含银行里中每一个用户的账号.
表: Transactions
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| trans_id | int |
| account | int |
| amount | int |
| transacted_on | date |
+---------------+---------+
trans_id 是该表主键.
该表的每一行包含了所有账户的交易改变情况.
如果用户收到了钱, 那么金额是正的; 如果用户转了钱, 那么金额是负的.
所有账户的起始余额为 0.
写一个 SQL, 报告余额高于 10000 的所有用户的名字和余额. 账户的余额等于包含该账户的所有交易的总和.返回结果表单没有顺序要求.
查询结果格式如下例所示.
Users table:
+------------+--------------+
| account | name |
+------------+--------------+
| 900001 | Alice |
| 900002 | Bob |
| 900003 | Charlie |
+------------+--------------+
Transactions table:
+------------+------------+------------+---------------+
| trans_id | account | amount | transacted_on |
+------------+------------+------------+---------------+
| 1 | 900001 | 7000 | 2020-08-01 |
| 2 | 900001 | 7000 | 2020-09-01 |
| 3 | 900001 | -3000 | 2020-09-02 |
| 4 | 900002 | 1000 | 2020-09-12 |
| 5 | 900003 | 6000 | 2020-08-07 |
| 6 | 900003 | 6000 | 2020-09-07 |
| 7 | 900003 | -4000 | 2020-09-11 |
+------------+------------+------------+---------------+
Result table:
+------------+------------+
| name | balance |
+------------+------------+
| Alice | 11000 |
+------------+------------+
Alice 的余额为(7000 + 7000 - 3000) = 11000.
Bob 的余额为1000.
Charlie 的余额为(6000 + 6000 - 4000) = 8000.
解题思路(1. transactions表和users表进行连接 inner join 2. 对临时表进行搜索得出名字和总金额 这里使用 sum group by 3. 使用最笨的方法将步骤2中临时表中的大于10000的搜索出来)
select * from (select ne.NAME,sum(ne.amount) BALANCE from
(select t.account,t.amount,u.NAME from transactions t inner join users u on u.account=t.account) ne group by ne.account) ne1 where ne1.balance>10000;
leetcode(秃头进行中的过期少女)的回答:
select u.name, sum(amount) as balance
from transactions t join users u on t.account = u.account
group by t.account
having sum(amount) > 10000
事实证明(还是秃头少女牛),自己是真没想到;