6

2 つの郵便番号間の距離 (マイル単位) を計算する関数 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

リストが大きい場合、これには時間がかかる場合があります。これは、次の行に沿ったオラクル分析クエリで実行できるように感じます。

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

私が行った唯一の分析クエリは、「row_number over (partition by order by)」ベースであり、これで未知の領域に足を踏み入れています。これに関するガイダンスは大歓迎です。

4

4 に答える 4

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すると、その距離の半径内にいくつあるかを知ることができます。countrangezip_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;
/

注:質問でCOUNT(場所)とSUM(場所)を使用しましたが、COUNT(場所)であると想定しました

于 2009-06-24T07:51:56.853 に答える
1

指定された zip から正方形の半径内に ZIP のサブセットを作成することで同じ問題を解決し (簡単な計算: < または > NSWE radius )、サブセット内の各エントリを繰り返し処理して、必要な半径内にあるかどうかを確認しました。魔法のように機能し、非常に高速でした。

于 2009-06-27T23:42:52.083 に答える
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_availableN

于 2009-06-23T16:49:28.117 に答える
0

私の古いプロジェクトの1つで、部分的に同様の要件がありました...米国の2つの郵便番号間の距離を計算するために。同じ問題を解決するために、私は米国空間データを大いに活用しました。基本的には、ソースの郵便番号 (緯度、経度) と宛先の郵便番号 (緯度、経度) を取得するというアプローチでした。次に、上記に基づいて距離を取得する関数を適用しました。この計算を行うのに役立つ基本式は、次のサイトで入手できます。私もこのサイト を参照して結果を検証しました...

注: ただし、これはおおよその距離を提供するため、それに応じて使用できます。利点は、結果を取得するための超高速で構築されます。

于 2012-08-10T18:56:40.950 に答える