【发布时间】:2019-09-27 11:50:20
【问题描述】:
我想比较来自Table-1(比如colA, colX)的两列值,以检查它们是否在Table-2(比如colB, colD, colY, colZ)的列值范围内。也就是说,如果colA 介于colB-colD 之间,和/或colX 分别介于colY-colZ 之间。
我知道BETWEEN SYMMETRIC 在订单无关紧要时使用,例如(最小,最大)或(最大,最小)。下面是我创建的示例。
表格:
CREATE TABLE location (id int, lat float, lon float, gpstime int);
CREATE TABLE trips( trip_id int, lat_start float, lat_end float,
lon_start float, lon_end float, travel_mode text);
表值:
INSERT INTO location
SELECT 1, 41.2, 8.3, 11111 UNION ALL --both lat and lon in the interval
SELECT 2, 43.3, 8.5, 22222 UNION ALL --only lat meets criteria
SELECT 3, 44.0, 8.5, 33333 --only lon meets criteria
INSERT INTO trips
SELECT 1, 41.1, 41.9, 8.0, 8.8, 'foot' UNION ALL
SELECT 2, 43.1, 43.5, 9.5, 8.9, 'bus' UNION ALL
SELECT 3, 42.1, 42.8, 8.7, 8.0, 'metro'
任务:
目标是获取location 表中lat 或lon(或两者)碰巧满足条件的所有行(在trips 表中):lat 在lat_start-lat_end 之间; lon 在lon_start- lon_end 之间。
显然应该返回location 表的所有行:第 1 行满足所有条件,第 2 行和第 3 行满足任一条件。
预期结果:
+---------+-----------+------+-----+-------------+
| trip_id | timestamp | lat | lon | travel_mode |
+---------+-----------+------+-----+-------------+
| 1 | 11111 | 41.2 | 8.3 | foot |
| 2 | 22222 | 43.1 | 8.5 | bus |
| 3 | 33333 | 44.0 | 8.5 | metro |
+---------+-----------+------+-----+-------------+
所以我使用BETWEEN SYMMETRIC 尝试了不同的查询,但结果不正确。
查询-1:
SELECT trip_id, gpstime AS timestamp, lat, lon, travel_mode
FROM location
INNER JOIN trips
ON (lat BETWEEN SYMMETRIC lat_start AND lat_end)
AND (lon BETWEEN SYMMETRIC lon_start AND lon_end)
查询结果:
+---------+-----------+------+-----+-------------+
| trip_id | timestamp | lat | lon | travel_mode |
+---------+-----------+------+-----+-------------+
| 1 | 11111 | 41.2 | 8.3 | foot |
+---------+-----------+------+-----+-------------+
Query-2:搞砸了一切
SELECT trip_id, gpstime AS timestamp, lat, lon, travel_mode
FROM location
INNER JOIN trips
ON (lat, lon) BETWEEN SYMMETRIC (lat_start, lat_end) AND (lon_start, lon_end)
结果:
+---------+-----------+------+-----+-------------+
| trip_id | timestamp | lat | lon | travel_mode |
+---------+-----------+------+-----+-------------+
| 2 | 11111 | 41.2 | 8.3 | foot |
| 3 | 11111 | 41.2 | 8.3 | metro |
+---------+-----------+------+-----+-------------+
Query-3:最差的情况
SELECT trip_id, gpstime AS timestamp, lat, lon, travel_mode
FROM location
INNER JOIN trips
ON lat BETWEEN SYMMETRIC lat_start AND lat_end
UNION
SELECT trip_id, gpstime AS timestamp, lat, lon, travel_mode
FROM location
INNER JOIN trips
ON lon BETWEEN SYMMETRIC lon_start AND lon_end
结果:
+---------+-----------+------+-----+-------------+
| trip_id | timestamp | lat | lon | travel_mode |
+---------+-----------+------+-----+-------------+
| 1 | 11111 | 41.2 | 8.3 | foot |
| 1 | 22222 | 43.3 | 8.5 | foot |
| 1 | 33333 | 44 | 8.5 | foot |
| 2 | 22222 | 43.3 | 8.5 | bus |
| 3 | 11111 | 41.2 | 8.3 | metro |
| 3 | 22222 | 43.3 | 8.5 | metro |
| 3 | 33333 | 44 | 8.5 | metro |
+---------+-----------+------+-----+-------------+
问题:什么是达到预期结果的正确查询?
编辑:
根据收到的答案,建议在 Query-1 中使用 OR 而不是 AND,我在下面编辑我的问题以显示推荐查询的结果:
查询:
SELECT trip_id, gpstime AS timestamp, lat, lon, travel_mode
FROM location
INNER JOIN trips
ON (lat BETWEEN SYMMETRIC lat_start AND lat_end)
OR (lon BETWEEN SYMMETRIC lon_start AND lon_end);
查询结果如下:
+---------+-----------+------+-----+-------------+
| trip_id | timestamp | lat | lon | travel_mode |
+---------+-----------+------+-----+-------------+
| 1 | 11111 | 41.2 | 8.3 | foot |
| 3 | 11111 | 41.2 | 8.3 | metro |
| 1 | 22222 | 43.3 | 8.5 | foot |
| 2 | 22222 | 43.3 | 8.5 | bus |
| 3 | 22222 | 43.3 | 8.5 | metro |
| 1 | 33333 | 44 | 8.5 | foot |
| 3 | 33333 | 44 | 8.5 | metro |
+---------+-----------+------+-----+-------------+
【问题讨论】:
标签: sql postgresql resultset between