前言
練習sql語句,所有題目來自于力扣(https://leetcode.cn/problemset/database/)的免費數據庫練習題。
今日題目:
585.2016年的投資
表:Person
列名 | 類型 |
---|---|
pid | int |
tiv_2015 | float |
tiv_2016 | float |
lat | float |
lon | float |
pid 是這張表的主鍵(具有唯一值的列)。表中的每一行都包含一條保險信息,其中:
pid 是投保人的投保編號。tiv_2015 是該投保人在 2015 年的總投保金額,tiv_2016 是該投保人在 2016 年的總投保金額。lat 是投保人所在城市的緯度。題目數據確保 lat 不為空。lon 是投保人所在城市的經度。題目數據確保 lon 不為空。
編寫解決方案報告 2016 年 (tiv_2016) 所有滿足下述條件的投保人的投保金額之和:
- 他在 2015 年的投保額 (tiv_2015) 至少跟一個其他投保人在 2015 年的投保額相同。
- 他所在的城市必須與其他投保人都不同(也就是說 (lat, lon) 不能跟其他任何一個投保人完全相同)。
- tiv_2016 四舍五入的 兩位小數 。
我那不值一提的想法:
-
首先梳理表內容,題干只給了一張保險表,記錄了投保編號,投保人2015年的總投保金額,2016年的總投保金額,投保人所在城市的維度和經度
-
其次分析需求,需要求滿足以下條件投保金額之和
-
1.在2015年的投保額至少跟一個其他投保人在2015年的投保額相同
- 在這個地方就有兩個思路:
- a.通過自連接,然后判斷條件pid相同,tiv_2015不同
- b.通過子查詢查詢臨時表。建立一個臨時表,這個臨時表對tiv_2015進行分組,只要tiv_2015的數量大于1,就證明至少有一個是相等的。
- 在這個地方就有兩個思路:
-
2.他所在的城市必須與其他投保人都不同
通過子查詢,對lat,lon進行分組,使得lat和lon的數量等于1,這樣就可以保證
查詢結果的經緯度不重復 -
思路一
select round(sum(tiv_2016),2) as tiv_2016
from Insurance
where tiv_2015
in
( select tiv_2015from Insurancegroup by tiv_2015having count(*) > 1
)
and (lat,lon)
in
(select lat,lonfrom Insurancegroup by lat,lonhaving count(lat) = 1 and count(lon) = 1
)
- 思路二
select round(sum(distinct i1.tiv_2016),2) as tiv_2016
from Insurance i1 ,Insurance i2
where i1.pid != i2.pid
and i1.tiv_2015 = i2.tiv_2015
and (i1.lat,i1.lon)
in
(select lat,lonfrom Insurancegroup by lat,lonhaving count(lat) = 1 and count(lon) = 1
)
結果:
- 思路一
- 思路二
總結:
能運行就行。