5k Aufrufe
Gefragt in Datenbanken von
Habe eine Abfrage an eine MDB-Tabelle:

SELECT PLZ, Ort, Lat, Lon
FROM Deutschland
WHERE SQR(((Lat - 52)^2) + ((Lon - 10)^2))<= 1;

Leider funzt diese nicht, da die Felder Lat und Lon als Text in der Tabelle definiert sind.
Wie kann ich mit den Werten der Felder trotzdem rechnen?
Kann man diese konvertieren?
Mit Val oder WERT komme ich hier nicht weiter.

Danke für einen Tipp
luet

24 Antworten

0 Punkte
Beantwortet von
Hi Ralf,

ich glaube ich habe es jetzt!
Du warst mir eine große Hilfe, dickes DANKE!
Klasse Forum :-)

Wenn du Verbesserungen für den u.g. Source hast, so poste das gerne.
Ich lerne gerne dazu, denn SQL ist nur ein Randthema für mich.

SelectStatement = "SELECT PLZ, Ort, KFZKennz, Bundesland, DistanzInKm FROM (SELECT PLZ, Ort, KFZKennz, Bundesland, " + _
"3.14159265358979 AS PI, " + _
"Cdbl(iif(instr(1, lat, ""."") = 0, lat, left(lat, instr(1, lat, ""."") - 1) & "","" & mid(lat, instr(1, lat, ""."")+1))) * PI / 180 AS hn, " + _
"Cdbl(iif(instr(1, lon, ""."") = 0, lat, left(lon, instr(1, lon, ""."") - 1) & "","" & mid(lon, instr(1, lon, ""."")+1))) * PI / 180 AS he, " + _
LaB + " * PI / 180 AS n, " + _
LoB + " * PI / 180 AS e, " + _
"COS(he - e) * COS(hn) * COS(n) + SIN(hn) * SIN(n) AS co, " + _
"atn(ABS(sqr(1 - co * co) / co)) AS ca, " + _
"Format(6367 * iif(co < 0, PI - ca, ca),""000.000"") AS DistanzInKm " + _
"FROM Deutschland) as innertab WHERE DistanzInKm " & Operator & " " & Entfernung + " Order by DistanzInKm ASC;"
0 Punkte
Beantwortet von rahi Experte (1.5k Punkte)
Hallo luet,

das "as innertab" ist nur ein sogenannter ALIAS und kann in diesem Fall sogar ganz weg gelassen werden. Dein SQL-String sind jetzt wirklich gut aus. Du kennst die Sytntax "SELECT * FROM TABELLE". Der Tabellenname TABELLE kann auch aus einem SELECT-Statement bestehen, dann muss dieses Statement nur geklammert werden, also "SELECT * FROM (SELECT * FROM TABELLE)", mehr ist da nicht dran.
Wie verwendest du denn dein SQL-String im weiteren Verlauf? Öffnest du damit einen Recordset (DAO oder ADODB)? Wenn ja, was machst du damit? Eventuell es es einfacher cursorgesteuert (Recordset), statt mengengesteuert (SELECT-Statement) vorzugehen. Brauchst du für deine Anwendung wirklich den Abstand?
Ich habe das mal für eine Reisekostenabrechnung verwendet, musste aber feststellen, das der Abstand für die Entfernung auf den Straßen ziemlich ungenau ist.

Gruß
Ralf
0 Punkte
Beantwortet von
Hi Ralf,

mit der Abfrage erstelle ich ein Recordset, das wiederum ein Datengrid füllt.
Hast du dafür Verbesserungsmöglichkeiten?
Thx
luet

Set daoDB36 = DBEngine.OpenDatabase(sPath)
Set rs2 = daoDB36.OpenRecordset(Abfrage)
Set Grid .Recordset = rs2
0 Punkte
Beantwortet von
Hallo Ralf,

hast du noch einen Tipp?
Wenn in der Datenbank unter Lat oder Lon kein Wert steht scheitert die Abfrage.
Wie kann ich das Filtern ? Where Lat Is Not Null ?
thx
luet



SelectStatement = "SELECT Id, PLZ, Ort, " + strKFZ + "Bundesland, DistanzInKm FROM (SELECT Id, PLZ, Ort, " + strKFZ + "Bundesland, " + _
"3.14159265358979 AS PI, " + _
"Cdbl(iif(instr(1, lat, ""."") = 0, lat, left(lat, instr(1, lat, ""."") - 1) & "","" & mid(lat, instr(1, lat, ""."")+1))) * PI / 180 AS hn, " + _
"Cdbl(iif(instr(1, lon, ""."") = 0, lat, left(lon, instr(1, lon, ""."") - 1) & "","" & mid(lon, instr(1, lon, ""."")+1))) * PI / 180 AS he, " + _
LaB + " * PI / 180 AS n, " + _
LoB + " * PI / 180 AS e, " + _
"COS(he - e) * COS(hn) * COS(n) + SIN(hn) * SIN(n) AS co, " + _
"atn(ABS(sqr(1 - co * co) / co)) AS ca, " + _
"Format(6367 * iif(co < 0, PI - ca, ca),""000.000"") AS DistanzInKm " + _
"FROM " + country + ") as innertab WHERE DistanzInKm " & Operator & " " & Entfernung + " Order by DistanzInKm ASC;"
0 Punkte
Beantwortet von rahi Experte (1.5k Punkte)
Hallo luet,

hier dein SQL-String mit der Bedingung, dass "lat" oder "lon" (oder beide) nicht NULL sein dürfen. Ich habe nur die vorletzte Zeile eingefügt.
SelectStatement = "SELECT Id, PLZ, Ort, " + strKFZ + "Bundesland, DistanzInKm FROM (SELECT Id, PLZ, Ort, " + strKFZ + "Bundesland, " + _
"3.14159265358979 AS PI, " + _
"Cdbl(iif(instr(1, lat, ""."") = 0, lat, left(lat, instr(1, lat, ""."") - 1) & "","" & mid(lat, instr(1, lat, ""."")+1))) * PI / 180 AS hn, " + _
"Cdbl(iif(instr(1, lon, ""."") = 0, lat, left(lon, instr(1, lon, ""."") - 1) & "","" & mid(lon, instr(1, lon, ""."")+1))) * PI / 180 AS he, " + _
LaB + " * PI / 180 AS n, " + _
LoB + " * PI / 180 AS e, " + _
"COS(he - e) * COS(hn) * COS(n) + SIN(hn) * SIN(n) AS co, " + _
"atn(ABS(sqr(1 - co * co) / co)) AS ca, " + _
"Format(6367 * iif(co < 0, PI - ca, ca),""000.000"") AS DistanzInKm " + _
"FROM " + country + _
"where not( lat is null or lon is null)" + _
" ) as innertab WHERE DistanzInKm " & Operator & " " & Entfernung + " Order by DistanzInKm ASC;"

Gruß
Ralf
0 Punkte
Beantwortet von
Danke Ralf für deine schnelle Hilfe.

Leider funzt das nicht.

"Syntaxfehler in der from-Klausel"

thx
luet
0 Punkte
Beantwortet von
Fehlte ein Leerzeichen vor dem where, aber es geht immer noch nicht?
thx
luet
0 Punkte
Beantwortet von
Hallo,

die Fehlermeldung lautet jetzt

"Datentypen in Kriterienausdruck unverträglich"

Das passiert nur bei Tabellen die Nullwerte in Lat oder Lon haben!

Hat einer Rat?
Thx
luet
0 Punkte
Beantwortet von rahi Experte (1.5k Punkte)
Hallo luet,

stimmt ich habe ein Leerzeichen vor der WHERE-Klausel vergessen sorry. Der Rest ist wirklich ein harter Brocken! SQL hat hier einen Typfehler, den wir mit dem bisher eingeschlagenen Weg nicht weg bekommen (@all: wer da eine Lösung hat, wäre ich interessiert). Probleme bereiten die Werte für "e" und "n", was ich nicht nachvollziehen kann, daher eine andere Herangehensweise. Voraussetzung dafür wäre eine neue Tabelle. Bsp.: Tabellenname "RefLatLon" mit den zwei Feldern "latref" und "lonref" beide vom Typ Double. In diese beiden Felder der neuen Tabelle müssen die Werte von "LaB" und "LoB" rein. Dann funktioniert folgender Code:
Function SelectStatement(Entfernung As String, Operator As String, strKFZ As String, country As String) As String

SelectStatement = "SELECT Id, PLZ, Ort, " + strKFZ + "Bundesland, Format(DistanceInKm,""000.000"") AS strDistanceInKm " + _
" FROM (SELECT Id, PLZ, Ort, " + strKFZ + "Bundesland, " + _
" 3.14159265358979 AS PI, lat*PI/180 AS hn, lon*PI/180 AS he, latref*3.14159265358979/180 AS n, lonref*3.14159265358979/180 AS e, " + _
" COS(he-e)*COS(hn)*COS(n)+SIN(hn)*SIN(n) AS co, atn(ABS(sqr(1-co*co)/co)) AS ca, 6367.0*IIf(co<0,PI-ca,ca) AS DistanceinKM " + _
" FROM " + country + ", RefLatLon " + _
" where not( lat is null or lon is null)" + _
" ) as innertab " + _
" WHERE innertab.DistanceInKm " & Operator & " " & Entfernung + " Order by innertab.DistanceInKm ASC;"

End Function
Die Konstruktion "strKFZ + Bundesland" kann ich nicht nachvollziehen, wenn es bei dir mit deinen Tabellen funktioniert ist es gut. Im Post15 ist noch ein Fehler in der Stringzeile 4. Du verwendest dort "lat" statt "lon". Das solltest du noch korrigieren, falls du mit dieser Lösung weiter kommen willst. Die Ersetzung von "." durch "," braucht man nicht. Probiere es mal aus.

Gruß
Ralf
0 Punkte
Beantwortet von
Hi Ralf,

Fehler Stringzeile4 ist klar :-)

Konstruktion "strKFZ + Bundesland":
strKFZ ist eine Variable die beide der einen Tabelle als Spalte vorhanden ist, bei der anderen Tabelle nicht und dort wird nur ein Leestring übergeben.

Ganz verstehe ich dein Vorschlag nicht?
Neue Tabelle( RefLatLon) anlegen mit zwei Spalten und dort LaB und LoB rein??

Dieses wird auf ein Grid nur einmal je Abfrage benutzt.
LaB und LoB sind die Koordinaten einer Stadt.
Und diese beiden Werte werden auf alle anderen Werte der Tabelle ( 20.000) berechnet.
Lab und LoB sind Variablen und gehören doch in keine Tabelle?
Es sind doch je Abfrage nur zwei Werte, warum dafür eine Tabelle anlegen?

Verstehe den Sinn nicht?
thx
luet
...