Oracle分析问题

Jos*_*ush 6 oracle analytics minimum-size

给定一个函数zipdistance(zipfrom,zipto),它计算两个邮政编码和下表之间的距离(以英里为单位):

create table zips_required(
   zip varchar2(5)
);

create table zips_available(
   zip varchar2(5),
   locations number(100)
);
Run Code Online (Sandbox Code Playgroud)

我如何构建一个查询,它将从zips_required表返回给我每个邮政编码,以及产生和(位置)> = 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
Run Code Online (Sandbox Code Playgroud)

这可能需要一段时间才能列入大型列表.感觉这可以通过以下方式使用oracle分析查询来完成:

min() over (
  partition by zips_required.zip 
  order by zipdistance( zips_required.zip, zips_available.zip)
  --range stuff here?
) 
Run Code Online (Sandbox Code Playgroud)

我所做的唯一分析查询是基于"row_number over(按顺序分区)",我正在用这个进入未知区域.非常感谢任何有关这方面的指导.

Vin*_*rat 2

这就是我想出的:

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
Run Code Online (Sandbox Code Playgroud)
  1. 对于每个zip_required计算到 的距离并按zip_available距离对它们进行排序
  2. 对于每个zip_requiredcountrange都可以知道zip_availables该距离的半径内有多少个。
  3. 过滤器(首先,其中 COUNT(位置) > 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;
/
Run Code Online (Sandbox Code Playgroud)

注意:您在问题中使用了 COUNT(locations) 和 SUM(locations),我认为它是 COUNT(locations)