Oracle分析问题

时间:2009-06-23 16:42:09

标签: oracle analytics minimum-size

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

create table zips_required(
   zip varchar2(5)
);

create table zips_available(
   zip varchar2(5),
   locations number(100)
);

如何构建一个查询,它将从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

在大型列表中可能需要一段时间。感觉这可以通过以下方式进行oracle分析查询来完成:

min() over (
  partition by zips_required.zip 
  order by zipdistance( zips_required.zip, zips_available.zip)
  --range stuff here?
) 

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

4 个答案:

答案 0 :(得分: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
  1. 每个zip_required计算到zip_available的距离并按距离排序
  2. 对于每个zip_required count rangezip_availables可让您知道该距离范围内有多少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; /
  3. 过滤器(首先是COUNT(位置)&gt; N)
  4. 我曾经创建过示例数据:

    {{1}}

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

答案 1 :(得分:1)

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_available的数量小于N的最大距离{{1}}。

答案 2 :(得分:1)

我通过在给定的zip(简单数学:&lt;或&gt; NSWE半径)的方形半径内创建ZIP的子集来解决相同的问题,然后遍历子集中的每个条目以查看它是否在需要的半径。工作就像一个魅力,非常快。

答案 3 :(得分:0)

我在我的一个旧项目中有一些类似的要求......计算美国2个拉链码之间的距离。为了解决这个问题,我充分利用了美国空间数据。基本上,方法是获取源Zipcode(纬度,经度)和目标Zipcode(纬度,经度)。 现在我已经应用了一个函数来获得基于上面的距离。有助于进行此计算的基本公式可在following site中找到 我还参考this site ...

验证了结果

注意:然而,这将提供近似距离,因此可以相应地使用它。一旦构建了它的超高速获取结果的好处。