You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle数据库中无交叉连接计算酒店与景点直线距离的方案求助

解决Oracle中酒店与景点距离计算的问题(禁用CROSS JOIN)

首先,你遇到的「single row subquery returns more than one row」错误,大概率是因为你在SELECT子句里嵌套了返回多行结果的子查询(比如试图为每一家酒店一次性获取所有景点的距离)——Oracle会默认认为这类子查询应该只返回一行数据,但实际返回了20行,所以触发报错。

要实现5家酒店×20个景点=100行的距离结果,同时不使用显式的CROSS JOIN关键字,我们可以用隐式笛卡尔积的写法(用逗号分隔两个预处理后的数据集),先分别关联酒店、景点与城镇表获取经纬度,再做全组合计算:

最终查询语句

SELECT 
    h.hotel_id,
    h.hotel_name,
    ta.attraction_id,
    ta.attraction_name,
    geodistance(h.hotel_lat, h.hotel_lon, ta.attraction_lat, ta.attraction_lon) AS straight_line_distance
FROM (
    -- 预处理:获取所有酒店的ID、名称及对应城镇的经纬度
    SELECT 
        hotel.hotel_id,
        hotel.hotel_name,
        town.town_latitude AS hotel_lat,
        town.town_longitude AS hotel_lon
    FROM HOTEL hotel
    INNER JOIN TOWN town ON hotel.town_id = town.town_id
) h,
(
    -- 预处理:获取所有景点的ID、名称及对应城镇的经纬度
    SELECT 
        attraction.attraction_id,
        attraction.attraction_name,
        town.town_latitude AS attraction_lat,
        town.town_longitude AS attraction_lon
    FROM "TOURIST ATTRACTION" attraction
    INNER JOIN TOWN town ON attraction.town_id = town.town_id
) ta
-- 按酒店和景点ID排序,方便结果查看
ORDER BY h.hotel_id, ta.attraction_id;

为什么这个写法符合要求?

  • 没有使用显式的CROSS JOIN关键字,而是用逗号分隔两个预处理后的数据集,Oracle会自动生成两个集合的笛卡尔积(即所有酒店与景点的组合),正好得到你需要的100行数据。
  • 先通过INNER JOIN分别关联酒店/景点与城镇表,提前获取到各自的经纬度,避免了嵌套子查询导致的单行返回错误。

如果你严格禁止任何形式的笛卡尔积(包括隐式的),还可以用递归CTE生成所有行号组合再关联数据,但这种写法更复杂,对于你的数据量(5×20)来说完全没必要,上面的写法已经足够简洁高效。

内容的提问来源于stack exchange,提问作者Big Rick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:21:27