2009-04-27 6 views
1

Ich muss eine Liste der UK Postleitzahlen in Reihenfolge sortieren.Sortieren Postleitzahl für Menü/Liste

Gibt es einen einfachen Weg, es zu tun?

UK Postleitzahlen besteht aus Buchstaben und Zahlen aus:

sehen für die vollständigen Informationen über das Format: http://en.wikipedia.org/wiki/UK_postcodes

Aber mein Problem ist dies eine einfache Alpha Art nicht funktioniert, weil jeder Code beginnt mit 1 oder zwei Buchstaben Buchstaben und dann folgt sofort eine Zahl, bis zu zwei Ziffern, dann ein Leerzeichen eine andere Zahl als ein Buchstabe. z.B. LS1 1AA oder LS28 1AA, gibt es auch einen anderen Fall, in dem, wenn die Zahl im ersten Abschnitt 99 übersteigt dann geht es weiter 9A usw.

Alpha sort verursachen die 10s, sofort die 1 folgen:

... 
LS1 9ZZ 
LS10 1AA 
... 
LS2 

I Ich suche eine SQL-Funktion zu erstellen, um die druckbare Postleitzahl in eine sortierbare Postleitzahl umzuwandeln, z 'LS1 9ZZ' würde 'LS01 9ZZ' werden, dann benutze diese Funktion in der order by-Klausel.

Hat jemand dieses oder etwas Ähnliches bereits getan?

+0

Ich denke, ein Menü oder eine Liste von Postleitzahlen für (vermutlich) der Benutzer zur Auswahl ist eine ziemlich unangenehme Benutzeroberfläche, es sei denn die Liste kann wirklich kurz gehalten werden. Und es ist möglich, dass Alpha-Sort ist so gut wie alles, wenn Sie dies wirklich tun müssen - meine Arbeit Postleitzahl passt nicht zu Ihrem Muster - es ist ec1a 2ay. Wo würdest du das in die sortierte Liste aufnehmen wollen? –

+0

Einverstanden - ich werde die UI-Methode ändern. – Adrian

Antwort

4

Sie müssen dies als tokenization Problem denken, so SW1A 1AA tokenize sollte:

  • SW
  • A
  • 1AA

(obwohl man konnte zerbrich den inneren Teil in 1 und AA, wenn du willst)

und G12 8QT sollte tokenize:

  • G
  • (leere Zeichenkette)
  • 8QT

Sobald Sie die Postleitzahl nach unten in diese Einzelteile zerlegt haben dann das Sortieren sollte einfach genug sein. Es gibt eine Ausnahme mit der Postleitzahl GIR 0AA, aber Sie können nur einen Test für diese eine

bearbeiten codieren: ein paar Gedanken auf tokenization

Für die Probe Postleitzahl SW1A 1AA, ist SW die PLZ-Gebiet, 1A ist der PLZ-Bezirk (den wir für Sortierzwecke in zwei Teile aufteilen), 1 ist der PLZ-Sektor und AA ist die Postleitzahl der Einheit.

Dies sind die gültigen Postleitzahl Formate (Quelle: Royal Mail PAF Benutzerhandbuch Seite 8 - Link am Ende des this page):

AN NAA
AAN NAA
ANN NAA
ANA NAA
AAA NAA (nur für GIR 0AA Code)
AANN NAA
AANA NAA

So ein grober Algorithmus würde (vorausgesetzt, wir wollen se parate den Sektor und die Einheit PLZ):

  • code = GIR 0AA? Tokenize zu GI/R// 0/AA (Behandlung von R wie der Bezirk vereinfacht Dinge)
  • Code 5 Buchstaben lang, zum Beispiel G1 3AF? Tokenize to G/1// 3/AF
  • Code 6 Buchstaben lang, wobei das 3. Zeichen ein Buchstabe ist, z.B. W1P 1HQ? Tokenize to W/1/P/1/HQ
  • Code 6 Buchstaben lang, wobei das zweite Zeichen ein Buchstabe ist, z. CR2 6XH? Tokenize to CR/2// 6/XH
  • Code 7 Buchstaben lang, wobei das vierte Zeichen ein Buchstabe ist, z. EC1A 1BB? Tokenize to EC/1/A/1/BB
  • ansonsten z.B. TW14 2ZZ, zu TW/14// 2/ZZ

tokenize Wenn der Zweck eine Liste der Postleitzahlen für den Benutzer anzuzeigen ist zu wählen, dann würde ich Neil Butterworths Vorschlag des Speicherns einer ‚sortierbar‘ -Version von adoptieren die Postleitzahl in der Datenbank. Der einfachste Weg, eine sortierbare Version zu erstellen, ist auf Pad alle Einträge zu neun Zeichen:

  • zwei Zeichen für den Bereich (rechts-pad, wenn kürzer)
  • zwei für den Bezirk Nummer (links-Pad, wenn kürzer)
  • ein für den Bezirk Brief (Pad, wenn sie fehlt)
  • Raum
  • ein für den Sektor
  • zwei für die Einheit

und GIR 0AA ist wieder eine kleine Ausnahme. Wenn Sie mit Leerzeichen auffüllen, sollte die Sortierreihenfolge korrekt sein. Beispiele unter Verwendung eines # Raum darzustellen:

  • W1 # 1AA => W 1 ## ## 1AA
  • WC1 # 1AA => WC# 1 ## 1AA
  • W10 # 1AA => W # 10 ## 1AA
  • W1W # 1AA => W 1 W # ## 1AA
  • GIR # 0AA => GI # R ## 0AA
  • WC10 # 1AA => ## WC10 1AA
  • WC1W # 1AA => WC# 1W # 1AA

Sie müssen den Bereich rechts auffüllen, wenn er zu kurz ist: linkes Auffüllen erzeugt die falsche Sortierreihenfolge. Alle einzelnen Buchstabenbereiche - B, E, G, L, M, N, S, W - würden vor allen Zwei-Buchstaben-Bereichen sortieren - AB, AL, ...ZE, - wenn Sie links gepolsterte

Die Bezirksnummer muss gepolstert gelassen werden, um sicherzustellen, dass die natürliche W1, W2, ..., W9, W10 bestellen

+0

Obwohl die 'Tokenisierung' nicht direkt ist, weil es nicht die üblichen Trennzeichen gibt .... – Adrian

+0

Ich habe einen groben Algorithmus zum Tokenizing hinzugefügt und einige Ideen, wie man die Ergebnisse speichert – barrowc

+0

danke - ich kann Sie nicht als Antwort markieren noch mehr, hoffentlich jemand anderes. – Adrian

1

Ich wäre versucht, die normalisierte Postleitzahl in der Datenbank zusammen mit der realen Postleitzahl zu speichern - so machen Sie nur die String-Manipulation einmal, und Sie können einen Index verwenden, um Sie mit der Sortierung zu helfen.

2

intakt bleibt Ich weiß, das ist ein paar Jahre spät, aber auch ich habe gerade dieses Problem erlebt. Ich habe es geschafft, es mit dem folgenden Code zu übertreffen, dachte also, ich würde teilen, wie ich das Internet suchte und nichts finden konnte!

mysql_query("SELECT SUBSTRING_INDEX(postcode,' ',1) as p1, SUBSTRING_INDEX(postcode,' ',-1) as p2 from `table` ORDER BY LENGTH(p1), p1, p2 ASC"); 

Dieser Code wird ein Full UK Postleitzahl nehmen und spaltete es in 2.

Es wird dann durch die zweite, gefolgt von dem ersten Teil der Postleitzahl sortiert.