ST_DISTANCE_SPHERE 함수란?
MySQL에서 제공하는 지리 함수 중 하나로, 두 지점 사이의 거리를 구하는 데 사용한다.구의 표면을 이용하여 두 지점 사이의 최단 거리를 계산하고 이를 미터로 환산해준다.
ST_DISTANCE_SPHERE 함수의 사용법
ST_DISTANCE_SPHERE(point(lon1, lat1), point(lon2, lat2))
위 구문에서 lon1, lat1, lon2, lat2는 경도와 위도 값을 나타내다. 이 함수는 두 지점 사이의 거리를 미터 단위로 반환한다.
약간 헷갈리는게 우리가 위도/경도가 순서가 익숙한데 여기서는 경도, 위도 순이라는 점이다.
그럼 실제로 사용해보자.
부산시청과 서울시청과의 거리를 측정해볼텐데, 두 위치의 위경도는 여기서 구할 수 있다.
부산광역시청 경도 129.0758 위도 35.1800
서울특별시청 경도 126.9783 위도 37.5666
SELECT ST_DISTANCE_SPHERE(point(129.0758, 35.1800), point(126.9783,37.5666))
아래값을 반환하는데 325,078m 즉 최단거리 기준 325km 정도 나온다.
ST_DISTANCE_SPHERE 반경 구해보기
그럼 특정 위경도의 데이터를 활용하여 해당 반경에 해당되는 값을 찾는 MySQL 쿼리를 작성해보자.
테이블 준비
상호명과 주소, 위경도가 표기된 tbl_corp 테이블을 하나 만들고,
CREATE TABLE tbl_corp (
id INT PRIMARY KEY AUTO_INCREMENT,
corp_name VARCHAR(100),
address VARCHAR(200),
corp_lat FLOAT(10,6),
corp_lon FLOAT(10,6)
);
id는 테이블에서 각 행의 고유한 식별자, corp_name은 상호명, address는 상호의 주소, corp_lat는 상호의 위치한 위도, corp_lon은 상호의 위치한 경도를 나타낸다.
#1. 특정 상호 반경 500m 내 상호명 개수 찾기
SELECT
srch.corp_name, COUNT(*) as count
FROM
(SELECT corp_name, corp_lon, corp_lat
FROM tbl_corp
WHERE corp_name = 'search_keyword' #기준 상호명) AS srch
JOIN
tbl_corp
ON ST_DISTANCE_SPHERE(point(srch.corp_lon, srch.corp_lon), point(corp_lon , corp_lat)) <= 500 #반경 500m
GROUP BY
srch.corp_lat, srch.corp_lon
#2. 특정 상호 반경 500m 내 상호명 거리순으로 오름차순(가까운 순으로)
SELECT
srch.srch_name, corp_name, corp_lat, corp_lon
FROM
(SELECT corp_name AS srch_name, corp_lon, corp_lat
FROM tbl_corp
WHERE corp_name = 'search_keyword' #기준 상호명) AS srch
JOIN
tbl_corp
ON ST_DISTANCE_SPHERE(point(srch.corp_lon, srch.corp_lon), point(corp_lon , corp_lat)) <= 500 #반경 500m
GROUP BY
srch.corp_lat, srch.corp_lon
ORDER BY
ST_DISTANCE_SPHERE(point(srch.corp_lon, srch.corp_lon), point(corp_lon , corp_lat)) ASC
이렇게 하면 셀프조인을 활용하여 테이블 내 두 지점 간 거리와 반경 내 상호 등 다양한 관점의 데이터를 추출해볼 수 있다.
'데이터 > SQL' 카테고리의 다른 글
[MySQL] Chat GPT로 샘플 데이터베이스 만들기 (0) | 2023.06.28 |
---|---|
[MySQL] 변수값으로 where절 필터를 설정하는 동적쿼리 (0) | 2023.05.16 |
[MySQL] Order by 구문으로 숫자가 정렬되지 않을 때 (0) | 2022.11.16 |
[MySQL] 정규 표현식(instr(), like(), replace(), substr()) (0) | 2022.10.31 |
[MySQL] 없는 시간 표시하기(재귀적 CTE) (0) | 2022.10.26 |
댓글