按距离(由近及远)排序符合条件项目的SQL查询问题
问题分析与解决方案
你尝试的SQL语句无法运行的核心原因是:l1是EXISTS子查询内部定义的别名,外部查询(包括ORDER BY子句)无法访问这个别名,导致引用无效。
以下是两种可行的解决方案,均能实现按距离由近及远排序的需求:
方案一:通过JOIN关联表直接计算距离
这种方式更直观,将地址、位置表直接关联到主查询中,直接获取经纬度计算距离并排序:
SELECT p.*, calculate_distance(43.7731408,-79.2317523,l.latitude,l.longitude,'K') AS distance FROM public.project p JOIN public.quotes q ON p.id = q.project_id JOIN public.address a ON p.address_id = a.id JOIN public.Location l ON a.postal_code = l.postal_code WHERE q.status = 'ACCEPTED' AND calculate_distance(43.7731408,-79.2317523,l.latitude,l.longitude,'K') <= 10.0 ORDER BY distance ASC;
- 说明:使用
INNER JOIN替代原有的LEFT JOIN,因为WHERE条件已经过滤了q.status = 'ACCEPTED',无需保留无匹配报价的项目; ORDER BY distance ASC实现距离由近及远排序,若要由远及近则改为DESC。
方案二:保留EXISTS过滤逻辑,子查询计算距离
如果需要保留原有的EXISTS过滤结构,可以在主查询中通过子查询获取对应项目的距离:
SELECT p.*, (SELECT calculate_distance(43.7731408,-79.2317523,l.latitude,l.longitude,'K') FROM public.Location l JOIN public.address a ON a.postal_code = l.postal_code WHERE a.id = p.address_id) AS distance FROM public.project p JOIN public.quotes q ON p.id = q.project_id WHERE q.status = 'ACCEPTED' AND EXISTS(SELECT 1 FROM public.Location l JOIN public.address a ON a.postal_code = l.postal_code WHERE a.id = p.address_id AND calculate_distance(43.7731408,-79.2317523,l.latitude,l.longitude,'K') <= 10.0) ORDER BY distance ASC;
- 说明:EXISTS子句仅用于过滤符合距离条件的项目,主查询通过子查询单独计算每个项目的距离,再用于排序。
内容的提问来源于stack exchange,提问作者Kunal Manchanda
相关产品推荐
相关产品推荐

