事情的起因
前言
这个题目其实还挺刁钻的,贴别是(lat,lon)是一个坐标,两个字段合成一个字段,然后,你得去给他们去重,当然咯,做题最重要的其实是审题,只有把题目的要求全部理解清楚了,那么才能完全写好解,这题作为exists用法的理解最合适不过了,估计这题很多方法都不如用exists
审题
这个题目主要有两个点,应该是找出tiv2015存在2条或者以上的数据,第二个就是lat和lon合在一起的时候要是整个数据里面唯一的
我的解
SELECT CAST(round(SUM(tiv_2016 ),2) AS DECIMAL(18,2)) as tiv_2016 FROM Insurance WHERE pid IN(
SELECT a.pid FROM Insurance a LEFT JOIN Insurance b
ON a.tiv_2015 =b.tiv_2015 where a.pid!=b.pid )
AND lat IN (SELECT lat FROM Insurance GROUP BY lat,lon HAVING COUNT(1)=1)
AND lon IN (SELECT lon FROM Insurance GROUP BY lon,lat HAVING COUNT(1)=1)
对自己解的分析
我其实写的很暴力,首先通过联表拿到所有tiv2015存在2条相等数据的pid,这个其实有不足奥,当时只想着相等的数据,我看到了个更好的是去分组tiv2015,只要它有2条数据或者以上,就可以去拿到所有的tiv2015,这样其实相当于拿到了所有的pid,那种写法会更简洁一点,然后在处理lat和lon我是直接暴力分组,相当于拿到所以去重过的(lat,lon)组合,然后再去挨个对他们进行处理,这里可以优化把公共语句提取用with包一下,整体写的还是比较偏暴力
最优解
select
round(sum(i1.tiv_2016),2 ) tiv_2016
from insurance i1
where exists (
select
i2.pid
from insurance i2 where i2.pid != i1.pid and i2.tiv_2015 = i1.tiv_2015
)
and not exists (
select
i2.lat, i2.lon
from insurance i2 where i2.pid != i1.pid and i2.lat = i1.lat and i2.lon = i1.lon
)
对最优解的分析
首先通过exists拿到相当于tiv2015存在2条的数据然后再通过not exists去排除掉(lat,lon)组合存在2条的数据,确实这个处理,逻辑很明细,代码也比较整洁