2012-04-14 5 views
0

Googleマップでフリーマーケットを立てるためのシンプルなWebアプリケーションを作成しました。 各スタンドは、ジオロケーションおよびその他の情報とともにsqlite3データベースに格納されています。 これは、スタンドテーブルのCREATE文です:SQL内の一致しないジオロケーションクエリの結果

CREATE TABLE stands (
id INTEGER PRIMARY_KEY, 
name TEXT, 
address TEXT, 
u REAL, 
v REAL, 
); 

uとvはそれぞれ緯度と経度です。 また、私は、スタンドをホストする各都市の名前と地理的境界を格納するcitiesテーブルを持っています。これはユーザーが都市間をすばやく移動できるようにするために使用されます。

CREATE TABLE cities 
(name TEXT PRIMARY_KEY, 
u_min REAL, 
u_max REAL, 
v_min REAL, 
v_max REAL); 

新しいスタンドが追加されると、新しい行が都市のテーブルに追加されたり、スタンドが知られている都市である場合、必要に応じて、都市の唯一の境界が更新されます。ここで

いくつかのサンプルが立っている:

592077673|Kierrätystori Rovaniemellä|Urheilukatu 1, 96100 Rovaniemi, Suomi|66.4978306921681|25.7220569153442 
1321495145|Kruununhaka|Liisankatu, 00170 Helsinki, Suomi|60.1742596|24.9555782  
571688977|Viikki asukastalo LAVAn edusta|Biologinkatu 5, 00790 Helsinki, Suomi|60.2342312|25.04058 
563089951|Hämeentie 156|Hämeentie 156, 00560 Helsinki, Suomi|60.2130467082539|24.9785856067459  
518892420|Joensuu - Ilosaari|Siltakatu 1, 80100 Joensuu, Finland|62.5990455742272|29.7706540507875 

と都市:

Rovaniemi|66.4978306921681|66.4978306921681|25.7220569153442|25.7220569153442 
Helsinki|60.1577049447137|60.2556221042622|24.9216988767212|25.0662129772156 
Järvenpää|60.4513724|60.4513724|25.0819323000001|25.0819323000001 
Joensuu|62.5990455742272|62.5990653244875|29.7706540507874|29.7706540507875 
Vantaa|60.2731724937748|60.2731724937748|24.9571491285278|24.9571491285278 

私がいる問題は、都市ごとのスタンド数を取得しています。 これまでのところ、私は次のクエリを使用してきた:

SELECT cities.name AS city, 
    cities.u_min, 
    cities.u_max, 
    cities.v_min, 
    cities.v_max, 
    count(stands.id) AS count 
FROM cities 
LEFT OUTER JOIN stands 
    ON ((stands.u BETWEEN cities.u_min AND cities.u_max) 
    AND(stands.v BETWEEN cities.v_min AND cities.v_max)) 
GROUP BY cities.name; 

これが返されます。ヨエンスーという名前の都市がその境界で1台を持っているとして正しくない

Helsinki|60.1577049447137|60.2556221042622|24.9216988767212|25.0662129772156|9 
**Joensuu|62.5990455742272|62.5990653244875|29.7706540507874|29.7706540507875|0** 
Järvenpää|60.4513724|60.4513724|25.0819323000001|25.0819323000001|1 
Rovaniemi|66.4978306921681|66.4978306921681|25.7220569153442|25.7220569153442|1 
Vantaa|60.2731724937748|60.2731724937748|24.9571491285278|24.9571491285278|1 

を:

518892420|Joensuu - Ilosaari|Siltakatu 1, 80100 Joensuu, Finland|62.5990455742272|29.7706540507875 

ただし、次のクエリは予想されるスタンドを返します。

SELECT * FROM stands where u between 62.5990455742272 and 62.5990653244875 and v between 29.7706540507874 and 29.7706540507875; 

ここで間違っていることは本当に理解できません。 ご協力いただければ幸いです。

ところで、私はこのデータベースをMysqlにインポートしました。同じことが起こるので、これはsqlite3のバグです。

答えて

1

これは浮動小数点精度エラーと関係があると思います。そのような問題に対処する方法の1つは、少数を導入して境界に追加して、それらを少し広くすることです。これは精度の誤差を排除します。

一つのアプローチは、直接、すべてのクエリに境界を広げることである。

SET @e = 0.0000000000001; 

SELECT cities.name AS city, 
    cities.u_min, 
    cities.u_max, 
    cities.v_min, 
    cities.v_max, 
    count(stands.id) AS count 
FROM cities 
LEFT OUTER JOIN stands 
    ON ((stands.u BETWEEN cities.u_min - @e AND cities.u_max + @e) 
    AND(stands.v BETWEEN cities.v_min - @e AND cities.v_max + @e)) 
GROUP BY cities.name; 

別のアプローチは、都市のテーブルに広がった境界を格納することです:

SET @e = 0.0000000000001; 

UPDATE cities 
SET cities.u_min = cities.u_min - @e, 
    cities.u_max = cities.u_max + @e, 
    cities.v_min = cities.v_min - @e, 
    cities.v_max = cities.v_max + @e; 

P.S.変数の構文がSQLiteで動作するかどうかはわかりませんが、そうでない場合は@e0.0000000000001に置き換えてください。

+0

それは非常にうまくいった、ありがとうございました! – Jonsku

+0

いいえ、SET構文はsqliteではサポートされていません。私は手動でデータベースにパッチを当て、データベーストランザクションを処理するPHPスクリプトを変更して、作成と更新時の境界を広げました。 – Jonsku

+0

私はあなたがそれが働いてうれしいです。 –

0

LEFT JOINを使用するのは、standsテーブルに一致するかどうかにかかわらず、すべての都市を含むからです。 COUNTがその行に0を返す方法に注意してください。

LEFT JOINの代わりにINNER JOINを使用してください。これは、MySQLに、ONの条件を満たす行だけを返すように指示します。

UPD:私はこの質問に間違いがあったので、この答えは間違っています。私は別の答えを掲示します。

+0

ありがとうございますが、INNER JOINは問題を解決しません。 Joensuu行のCOUNTは、都市の境界に立つため、0ではなく1を返します(Lat:62.5990455742272 - 62.5990653244875、Long:29.7706540​​507874 - 29.7706540​​507875):** 518892420 | Joensuu - Ilosaari | Siltakatu 1、80100 Joensuu、フィンランド| 62.5990455742272 | 29.7706540​​507875 ** \ n何らかの理由で問題がON状態のどこかにあり、スタンドがカウントされません。 – Jonsku

関連する問題