计算 2 个重复案例之间的地理距离
Calculate the geographic distance between 2 duplicated cases
我正在尝试计算数据库中 2 个重复案例之间的距离
我正在研究 SQL Oracle
例如:
ID ID_Household long lat
1 1 3.2 22.2
1 2 2.3 21.2
2 3 22.2 45.4
2 4 12.8 15.9
3 3 11.2 13.2
3 4 11.2 13.2
我希望输出为
ID duplication_status distance
1 2 more than 100 meter
3 2 less than 100 meter
我试图阅读很多文章和问题,但无法建立逻辑
How to calculate distance between multiple points in SQL Server?
你可以:
CREATE FUNCTION haversine_distance(
lat1 IN NUMBER,
long1 IN NUMBER,
lat2 IN NUMBER,
long2 IN NUMBER
) RETURN NUMBER DETERMINISTIC
IS
PI CONSTANT NUMBER := ASIN(1) * 2;
R CONSTANT NUMBER := 6371000; -- Approx. radius of the earth in m
PHI1 CONSTANT NUMBER := lat1 * PI / 180;
PHI2 CONSTANT NUMBER := lat2 * PI / 180;
DELTA_PHI CONSTANT NUMBER := (lat2 - lat1) * PI / 180;
DELTA_LAMBDA CONSTANT NUMBER := (long2 - long1) * PI / 180;
a NUMBER;
c NUMBER;
BEGIN
a := SIN(delta_phi/2) * SIN(delta_phi/2) + COS(phi1) * COS(phi2) *
SIN(delta_lambda/2) * SIN(delta_lambda/2);
c := 2 * ATAN2(SQRT(a), SQRT(1-a));
RETURN R * c; -- in metres
END;
/
然后使用查询:
SELECT id,
haversine_distance(lat1, long1, lat2, long2) AS distance_metres,
CASE
WHEN haversine_distance(lat1, long1, lat2, long2) > 100
THEN 'more than 100 meter'
ELSE 'less than 100 meter'
END AS distance
FROM table_name
MATCH_RECOGNIZE(
PARTITION BY id
ORDER BY id_household
MEASURES
FIRST(longitude) AS long1,
FIRST(latitude) AS lat1,
LAST(longitude) AS long2,
LAST(latitude) AS lat2
PATTERN ( house{2} )
DEFINE
house AS 1 = 1
);
或任何其他将行分组成对并旋转然后调用函数的方法。
其中,对于示例数据:
CREATE TABLE table_name (ID, ID_Household, longitude, latitude) AS
SELECT 1, 1, 3.2, 22.2 FROM DUAL UNION ALL
SELECT 1, 2, 2.3, 21.2 FROM DUAL UNION ALL
SELECT 2, 3, 22.2, 45.4 FROM DUAL UNION ALL
SELECT 2, 4, 12.8, 15.9 FROM DUAL UNION ALL
SELECT 3, 3, 11.2, 13.2 FROM DUAL UNION ALL
SELECT 3, 4, 11.2, 13.2 FROM DUAL;
输出:
ID
DISTANCE_METRES
DISTANCE
1
144947.804966182829942744055657720422603
more than 100 meter
2
3395725.11733156831056822390960787854383
more than 100 meter
3
0
less than 100 meter
或者,如果您想使用 SDO 几何函数:
SELECT id,
sdo_geom.sdo_distance(
sdo_geometry(
2001, -- 2D co-ordinate containing a single point
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(lat1,long1,null),
null,
null
),
sdo_geometry(
2001, -- 2D co-ordinate containing a single point
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(lat2,long2,null),
null,
null
),
0.005,
'unit=m'
) AS distance_metres,
CASE
WHEN sdo_geom.sdo_distance(
sdo_geometry(
2001, -- 2D co-ordinate containing a single point
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(lat1,long1,null),
null,
null
),
sdo_geometry(
2001, -- 2D co-ordinate containing a single point
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(lat2,long2,null),
null,
null
),
0.005,
'unit=m'
) > 100
THEN 'more than 100 meter'
ELSE 'less than 100 meter'
END AS distance
FROM table_name
MATCH_RECOGNIZE(
PARTITION BY id
ORDER BY id_household
MEASURES
FIRST(longitude) AS long1,
FIRST(latitude) AS lat1,
LAST(longitude) AS long2,
LAST(latitude) AS lat2
PATTERN ( house{2} )
DEFINE
house AS 1 = 1
)
输出:
ID
DISTANCE_METRES
DISTANCE
1
149223.001672844
more than 100 meter
2
3293714.72371264
more than 100 meter
3
0
less than 100 meter
db<>fiddle here
我正在尝试计算数据库中 2 个重复案例之间的距离 我正在研究 SQL Oracle
例如:
ID ID_Household long lat
1 1 3.2 22.2
1 2 2.3 21.2
2 3 22.2 45.4
2 4 12.8 15.9
3 3 11.2 13.2
3 4 11.2 13.2
我希望输出为
ID duplication_status distance
1 2 more than 100 meter
3 2 less than 100 meter
我试图阅读很多文章和问题,但无法建立逻辑 How to calculate distance between multiple points in SQL Server?
你可以
CREATE FUNCTION haversine_distance(
lat1 IN NUMBER,
long1 IN NUMBER,
lat2 IN NUMBER,
long2 IN NUMBER
) RETURN NUMBER DETERMINISTIC
IS
PI CONSTANT NUMBER := ASIN(1) * 2;
R CONSTANT NUMBER := 6371000; -- Approx. radius of the earth in m
PHI1 CONSTANT NUMBER := lat1 * PI / 180;
PHI2 CONSTANT NUMBER := lat2 * PI / 180;
DELTA_PHI CONSTANT NUMBER := (lat2 - lat1) * PI / 180;
DELTA_LAMBDA CONSTANT NUMBER := (long2 - long1) * PI / 180;
a NUMBER;
c NUMBER;
BEGIN
a := SIN(delta_phi/2) * SIN(delta_phi/2) + COS(phi1) * COS(phi2) *
SIN(delta_lambda/2) * SIN(delta_lambda/2);
c := 2 * ATAN2(SQRT(a), SQRT(1-a));
RETURN R * c; -- in metres
END;
/
然后使用查询:
SELECT id,
haversine_distance(lat1, long1, lat2, long2) AS distance_metres,
CASE
WHEN haversine_distance(lat1, long1, lat2, long2) > 100
THEN 'more than 100 meter'
ELSE 'less than 100 meter'
END AS distance
FROM table_name
MATCH_RECOGNIZE(
PARTITION BY id
ORDER BY id_household
MEASURES
FIRST(longitude) AS long1,
FIRST(latitude) AS lat1,
LAST(longitude) AS long2,
LAST(latitude) AS lat2
PATTERN ( house{2} )
DEFINE
house AS 1 = 1
);
或任何其他将行分组成对并旋转然后调用函数的方法。
其中,对于示例数据:
CREATE TABLE table_name (ID, ID_Household, longitude, latitude) AS
SELECT 1, 1, 3.2, 22.2 FROM DUAL UNION ALL
SELECT 1, 2, 2.3, 21.2 FROM DUAL UNION ALL
SELECT 2, 3, 22.2, 45.4 FROM DUAL UNION ALL
SELECT 2, 4, 12.8, 15.9 FROM DUAL UNION ALL
SELECT 3, 3, 11.2, 13.2 FROM DUAL UNION ALL
SELECT 3, 4, 11.2, 13.2 FROM DUAL;
输出:
ID DISTANCE_METRES DISTANCE 1 144947.804966182829942744055657720422603 more than 100 meter 2 3395725.11733156831056822390960787854383 more than 100 meter 3 0 less than 100 meter
或者,如果您想使用 SDO 几何函数:
SELECT id,
sdo_geom.sdo_distance(
sdo_geometry(
2001, -- 2D co-ordinate containing a single point
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(lat1,long1,null),
null,
null
),
sdo_geometry(
2001, -- 2D co-ordinate containing a single point
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(lat2,long2,null),
null,
null
),
0.005,
'unit=m'
) AS distance_metres,
CASE
WHEN sdo_geom.sdo_distance(
sdo_geometry(
2001, -- 2D co-ordinate containing a single point
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(lat1,long1,null),
null,
null
),
sdo_geometry(
2001, -- 2D co-ordinate containing a single point
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(lat2,long2,null),
null,
null
),
0.005,
'unit=m'
) > 100
THEN 'more than 100 meter'
ELSE 'less than 100 meter'
END AS distance
FROM table_name
MATCH_RECOGNIZE(
PARTITION BY id
ORDER BY id_household
MEASURES
FIRST(longitude) AS long1,
FIRST(latitude) AS lat1,
LAST(longitude) AS long2,
LAST(latitude) AS lat2
PATTERN ( house{2} )
DEFINE
house AS 1 = 1
)
输出:
ID DISTANCE_METRES DISTANCE 1 149223.001672844 more than 100 meter 2 3293714.72371264 more than 100 meter 3 0 less than 100 meter
db<>fiddle here