问题
I have 3 tables user, profile and location. The structure of these tables are:
user
table
user_id | email | pass | activated | banned
profile
table
user_id | name | birthday | picture | gender | last_active
location
table
user_id | city | country | latitude | longitude
Now here are search conditions:
- User must be activated(1) to appear in search result.
- User must not be banned(0).
- Search results must be nearby location according to latitude and longitude.
- search result must order by last active.
To display a search I will need user name, picture, city and country, age, gender and offline/online status.
I have a query to order by location:
SELECT
latitude, longitude,
SQRT( POW( 69.1 * ( latitude - 52.58 ) , 2 ) + POW( 69.1 * ( - 1.12 - longitude ) * COS( latitude / 57.3 ) , 2 ) ) AS distance
FROM
location
ORDER BY
distance
Can anyone contribute to build a codeignitor query for these conditions?
回答1:
you could try build around this query
select l.latitude, l.longitude,
SQRT( POW( 69.1 * ( l.latitude - 52.58 ) , 2 ) +
POW( 69.1 * ( - 1.12 - l.longitude ) * COS( l.latitude / 57.3 ) , 2 ) ) as distance
from user as u
left join profile as p
on p.user_id = u.id
left join location as l
on l.user_id = u.id
where u.activated=1 and u.banned=0
order by distance desc
May I suggest you lookup using foreign key constraints in mysql
回答2:
There are a number of other optmizations depending on how accurate you need to be and how fast you need it. I won't show you how to do that right here, but this is the basic codeIgniter query for what you asked:
$max_distance = 20;
$this->db
->select('*') // Change this to only the fields you need...
->select('SQRT( POW( 69.1 * ( latitude - 52.58 ) , 2 ) + POW( 69.1 * ( - 1.12 - longitude ) * COS( latitude / 57.3 ) , 2 ) ) AS distance')
->from('user')
->where('user.active', 1)
->where('user.banned !=', 0)
->where('distance <', $max_distance)
->join('location','location.user_id=user.user_id')
->join('profile','profile.user_id=user.user_id')
->order_by('last_active','desc')
->get();
Please note that distance calculation become slow as soon as you have hundreds of thousands of records. The most obvious optmization is to first limit the query with a box to cut down on having to calculate the distance for rows that are nowhere near, and then do the radius within that.
来源:https://stackoverflow.com/questions/8601148/complex-codeigniter-user-search-query