0

次のクエリがあります。

SELECT TeacherLocation.user_id, TeacherLocation.city, TeacherLocation.state_id, 
TeacherLocation.latitude, TeacherLocation.longitude,    

3959 * acos( cos( radians(40.76332092) ) * cos( radians( TeacherLocation.latitude ) )* 
cos( radians(   TeacherLocation.longitude ) - radians(-73.98623657) ) + sin(       
radians(40.76332092) ) * 
sin( radians( TeacherLocation.latitude ) )  ) AS distance 

FROM teacher_locations AS TeacherLocation

GROUP BY TeacherLocation.user_id
HAVING distance > 0
ORDER BY distance ASC LIMIT 0, 100

これは正常に機能しているように見えますが、私が抱えている問題は、user_id でグループ化していて、user_id がテーブル内で一意ではないため、最も近い距離を取得する可能性がありますが、常に都市であるとは限りません。その距離のstate_id(複数あるため)。結果:

user_id     city            stateId Lat             Long            Distance
83224   NEW YORK    33  40.751091   -73.99469757    0.954064642293979
87336   NEW YORK    33  40.751091   -73.99469757    0.954064642293979
87850   NEW YORK    33  40.751091   -73.99469757    0.954064642293979
86822   NEW YORK    33  40.751091   -73.99469757    0.954064642293979

min (距離) を追加すると、奇妙な結果が得られます。なんで?

4

1 に答える 1

2

次のようなフィルタリング結合を使用できます。

select  *
from    teacher_locations tl
join    (
        select  user_id
        ,       min(... distance formula here...) as MinDistance
        from    teacher_location
        group by
                user_id
        ) filter
on      filter.user_id = tl.user_id
        and filter.MinDisance = tl.(... distance formula here...)

速度が問題になる場合は、MySQL 変数トリックを使用できます。これは高速ですが、移植性がありません (おそらく、将来の MySQL バージョンにも移植できません)。

select  *
from    (
        select  @rn := if(user_id = @lastuserid, 1, @rn+1) as rn
        ,       @lastuserid := user_id
        ,       tl.*
        from    TeacherLocation tl
        cross join
               (select @rn := 0, @lastuserid := -1) as init
        order by
                tl.user_id
        ,       tl.distance desc
        ) as SubQueryAlias
where   rn = 1

SQL Fiddle の例では、距離の計算を自分で拡張する必要があります。

于 2012-07-28T09:33:05.807 に答える