题
给定一个函数zipdistance(zipfrom,zipto)来计算两个邮政编码和下表之间的距离(以英里为单位):
create table zips_required(
zip varchar2(5)
);
create table zips_available(
zip varchar2(5),
locations number(100)
);
如何构建一个查询,它将从zips_required表中返回每个邮政编码以及产生总和的最小距离(位置)<!> gt; = n。
到目前为止,我们只是运行一个详尽的循环查询每个半径,直到我们符合标准。
--Do this over and over incrementing the radius until the minimum requirement is met
select count(locations)
from zips_required zr
left join zips_available za on (zipdistance(zr.zip,za.zip)< 2) -- Where 2 is the radius
在大型列表中可能需要一段时间。感觉这可以通过以下方式进行oracle分析查询来完成:
min() over (
partition by zips_required.zip
order by zipdistance( zips_required.zip, zips_available.zip)
--range stuff here?
)
我所做的唯一分析查询是<!>“; row_number over(按顺序分区)<!>”;基于,我正在用这个进入未知领域。非常感谢任何有关这方面的指导。
解决方案
这就是我提出的:
SELECT zr, min_distance
FROM (SELECT zr, min_distance, cnt,
row_number() over(PARTITION BY zr ORDER BY min_distance) rnk
FROM (SELECT zr.zip zr, zipdistance(zr.zip, za.zip) min_distance,
COUNT(za.locations) over(
PARTITION BY zr.zip
ORDER BY zipdistance(zr.zip, za.zip)
) cnt
FROM zips_required zr
CROSS JOIN zips_available za)
WHERE cnt >= :N)
WHERE rnk = 1
- 每个
zip_required
计算到zip_available
的距离并按距离排序 - 对于每个
count
range
zip_availables
允许您知道有多少<=>在该距离的半径范围内。 - 过滤器(首先是COUNT(位置)<!> gt; N) 醇>
我曾经创建过示例数据:
INSERT INTO zips_required
SELECT to_char(10000 + 100 * ROWNUM) FROM dual CONNECT BY LEVEL <= 5;
INSERT INTO zips_available
(SELECT to_number(zip) + 10 * r, 100 - 10 * r FROM zips_required, (SELECT ROWNUM r FROM dual CONNECT BY LEVEL <= 9));
CREATE OR REPLACE FUNCTION zipdistance(zipfrom VARCHAR2,zipto VARCHAR2) RETURN NUMBER IS
BEGIN
RETURN abs(to_number(zipfrom) - to_number(zipto));
END zipdistance;
/
注意:您在问题中使用了COUNT(位置)和SUM(位置),我认为它是COUNT(位置)
其他提示
SELECT *
FROM (
SELECT zip, zd, ROW_NUMBER() OVER (PARTITION BY zip ORDER BY rn DESC) AS rn2
FROM (
SELECT zip, zd, ROW_NUMBER() OVER (PARTITION BY zip ORDER BY zd DESC) AS rn
FROM (
SELECT zr.zip, zipdistance(zr.zip, za.zip) AS zd
FROM zips_required zr
JOIN zips_available za
)
)
WHERE rn <= n
)
WHERE rn2 = 1
对于每个zip_required
,这将选择适合N
zip_available
的最小距离,或者如果<=>的数量小于<=>,则选择最大距离。
我通过在给定的zip(方便的数学:<!> lt;或<!> gt; NSWE半径)的方形半径内创建ZIP的子集来解决相同的问题,然后迭代子集中的每个条目看它是否在所需的半径范围内。工作就像一个魅力,非常快。
不隶属于 StackOverflow