Oracle Analytic Frage
-
06-07-2019 - |
Frage
Bei einer Funktion zipdistanz (Zipfrom, Zipto), die den Abstand (in Meilen) zwischen zwei Postleitzahlen und den folgenden Tabellen berechnet:
create table zips_required(
zip varchar2(5)
);
create table zips_available(
zip varchar2(5),
locations number(100)
);
Wie kann ich eine Abfrage erstellen, die zu mir jede Postleitzahl aus der Tabelle Zips_Required zurückkehrt, und die minimale Entfernung, die eine Summe erzeugt (Standorte)> = n.
Bis jetzt haben wir gerade eine erschöpfende Schlaufe -Abfrage für jeden Radius durchgeführt, bis wir die Kriterien erfüllt haben.
--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
Dies kann eine Weile auf einer großen Liste dauern. Es fühlt sich so an, als könnte dies mit einer Oracle Analytic -Abfrage in der Reihe von: gemacht werden:
min() over (
partition by zips_required.zip
order by zipdistance( zips_required.zip, zips_available.zip)
--range stuff here?
)
Die einzigen analytischen Abfragen, die ich durchgeführt habe, waren "row_number Over (Partition by Order by)", und ich trete damit in unbekannte Bereiche. Jede Anleitung dazu wird sehr geschätzt.
Lösung
Das habe ich mir ausgedacht:
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
- Für jeden
zip_required
Berechnen Sie den Abstand zumzip_available
und sortieren Sie sie nach Entfernung - Für jeden
zip_required
dascount
mitrange
ermöglicht es Ihnen zu wissen, wie vielezip_availables
sind im Radius dieser Entfernung. - Filter (zuerst, wo Graf (Standorte)> n)
Ich habe Beispieldaten erstellt:
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;
/
Notiz: Sie haben Count (Standorte) und Summe (Standorte) in Ihrer Frage verwendet.
Andere Tipps
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
Für jeden zip_required
, Dies wählt die minimale Entfernung aus, in die passen N
zip_available
's oder maximale Entfernung, wenn die Anzahl von zip_available
'S ist weniger als N
.
Ich habe das gleiche Problem gelöst, indem ich eine Teilmenge von ZIPs innerhalb eines quadratischen Radius aus dem gegebenen Reißverschluss (Easy Math: <oder> NSWE -Radius) erstellte und dann jeden Eintrag in der Teilmenge durch Iterien durchführte, um festzustellen, ob es sich innerhalb des benötigten Radius befand. Arbeitete wie ein Zauber und war sehr schnell.
Ich hatte teilweise ähnliche Anforderungen in einem meiner alten Projekte ... um den Abstand zwischen 2 Zipcodes in den USA zu berechnen. Um das Gleiche zu lösen, hatte ich uns räumliche Daten sehr verwendet. Grundsätzlich bestand der Ansatz darin, den Quell -Zipcode (Breitengrad, Längengrad) und Zielzipcode (Breitengrad, Länge) zu erhalten. Jetzt hatte ich eine Funktion angewendet, um die Entfernung basierend auf dem oben genannten zu erhalten. Die Basisformel, die bei dieser Berechnung hilft, ist in der verfügbar folgende SeiteIch hatte das Ergebnis auch validiert, indem ich mich auf den Hinweis auf Diese Seite...
Hinweis: Dies liefert jedoch ungefähre Entfernungen, sodass man dies entsprechend verwenden kann. Die Vorteile werden einmal erstellt, um die Ergebnisse zu erzielen.