문제
SQLite
함수 | 설명 |
radians(deg) | 각도를 라디안(radian) 단위로 변환 (Haversine 공식에서 필수) |
sin(x) | x 값(라디안)의 사인(sine) 값을 반환 |
cos(x) | x 값(라디안)의 코사인(cosine) 값을 반환 |
sqrt(x) | x의 제곱근(√x) 값을 반환 |
date() | 날짜 관련 연산을 수행하는 함수 |
asin | 아크사인(arc sine) 값을 계산하는 데 사용. 사인(sine) 값에 대한 역함수를 라디안 단위로 반환 |
// 거리 공식 sql로 변환
d = 2 * 6356 * asin(
sqrt(pow(sin(radians(abs(s1.lat-s2.lat)/2)),2)
+ cos(radians(s1.lat))*cos(radians(s2.lat))
* pow(sin(radians(abs(s1.lng-s2.lng)/2)),2)))
// 제곱하기 때문에 절대값 필요없음 -> 최종 공식
d = 2 * 6356 * asin(
sqrt(pow(sin(radians((s1.lat-s2.lat)/2)),2)
+ cos(radians(s1.lat))*cos(radians(s2.lat))
* pow(sin(radians((s1.lng-s2.lng)/2)),2)))
내가 작성한 정답
- 각각의 station_id와 station_id보다 최신에 수리된 다른 모든 아이디를 결합
- 그 중 거리가 300m보다 가까운 id들만 걸러냄
- 걸러진 id들을 세서 5개 이상이면 출력
select s1.station_id,s1.name
from station s1
join station s2 on s1.station_id != s2.station_id
and s1.updated_at < s2.updated_at
where 2*6356*asin(
sqrt(pow(sin(radians((s1.lat-s2.lat)/2)),2)
+ cos(radians(s1.lat))*cos(radians(s2.lat))
* pow(sin(radians((s1.lng-s2.lng)/2)),2))) * 1000 <= 300
group by s1.station_id
having count(distinct s2.station_id) >= 5
Share article