SQL:动态扩展搜索条件

3

我有一个包含本地商家坐标的表格(纬度,经度),我需要获取在给定半径内的所有商家,为此我使用一个查询,在查询中动态计算距离。

select b.* from `businesses` as b
where
(
1.609344 * 3956 * 2 * ASIN(
    SQRT( 
            POWER(SIN((lat - b.lat) *  pi()/180 / 2), 2) +
            COS(lat * pi()/180) * COS(b.lat * pi()/180) * 
            POWER(SIN((lng -b.lng) * pi()/180 /-2), 2) 
        )
    )
) <= radius

现在我需要在以下情况下扩大半径,即该地区的企业数量太少, 例如,如果在给定的半径范围内只有10家企业,则需要动态扩大半径直到获得50家企业。


你能否在WHERE子句中去除<= radius部分,将WHERE中的内容移到ORDER BY中,然后再加上LIMIT 50? - Ruslan
1
但如果超过50个,我需要看到它们全部。 - Dima K
哦,我明白了...在SQL Server中,我可能会使用递归CTE来处理这样的问题,但我认为MySQL中没有类似的结构。在你的情况下,我可能会创建一个带有临时表的存储过程,并用第一次结果填充它。如果少于50,则会循环查询并增加半径,直到达到50,然后返回该临时表。 - Ruslan
1个回答

1

只需计算给定点的距离并使用它进行排序,然后将结果数限制为50。

如果在该半径内立即有超过50个结果,则会变得有些棘手,如果您想要更多的结果,则需要采取一些措施。

在这种情况下,您可以执行类似“if distance < ? OR RowNum < 50”的子句。在MySQL中,创建行号的唯一方法是使用变量。

这将看起来像这样:

WITH t1 AS
(
    SELECT b.*,
    1.609344 * 3956 * 2 * ASIN(
                SQRT( 
                    POWER(SIN((lat - b.lat) *  pi()/180 / 2), 2) +
                    COS(lat * pi()/180) * COS(b.lat * pi()/180) * POWER(SIN((lng -b.lng) * pi()/180 / 2), 2) 
                )
            )
    ) AS distance
    FROM businesses as b
), t2 AS
(
     SELECT *, @rownum := @rownum + 1 AS row_num
     FROM t1, (SELECT @rownum := 0) r
     ORDER BY distance
)
SELECT * FROM t2
WHERE distance < ? OR row_num < ?

我忘了提到我正在使用MySql,它不支持ROW_NUMBER()。 - Dima K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接