codeigniter complex join only if rows don't exist

感情迁移 提交于 2019-12-25 07:16:40

问题


I'm making a dating application, much like tindler. Users can like or dislike other users, and if two users both like each other they get the option to chat with eachother. Currently building the query to pull a random profile and one of their pictures at random:

$data = $this->db
->select('users.id,display_name,city,state,gender,users_pictures.picture')
  ->join('users_pictures','users_pictures.user_id = users.id')
  ->order_by('id','RANDOM')
  ->limit(1)
  ->where(array('users.approved'=>1,'users_pictures.approved'=>1))
  ->where(array('users.id !='=>$user_id))->get('users')->result_array();    

Now here's where I'm confused.. I have a table for likes_dislikes that consists of user_id, foreign_user_id, and event_type (like, dislike).

If you disliked or liked a user already, I do not want them in my results. The only means I can think of handling this is to perform a second query which checks this, and then does another 'random' query if you have already liked/disliked them so that you only see users you haven't already rated. Is there a better way?

Any help is much appreciated :)


回答1:


Have you heard of the EXISTS and NOT EXISTS MySQL commands? The latter is the one you should try.

SELECT
 u.id, display_name, city, state, gender, up.picture
FROM
 users AS u
INNER JOIN
 users_pictures AS up ON up.user_id = u.id
WHERE
 NOT EXISTS(
    SELECT 
     1 
    FROM
     likes_dislikes
    WHERE
     ld.foreign_user_id = u.id AND ld.user_id = $loggedInUserId
 )

The above will list all users, excluding all liked/disliked users. Trying to form this SQL statement with Codeigniter without the value being binded is a little hacky.

A brief investigation via Google (which may now be outdated) suggests that the following should be suitable.

//...rest of query
$db->where("
  NOT EXISTS (
    SELECT 1 
    FROM likes_dislikes 
    WHERE ld.foreign_user_id = u.id AND ld.user_id = $loggedInUserId
  ) AND 1 = ", 1); 

Take notice to the last part AND 1 = ", 1);.




回答2:


This is not an answer, but I have little suggestion.

You can change like/dislike to numbers, -1 (dislike), 0 or NULL (unrated), 1 (like) for example.

It should simplify/shorten your queries.

After this - you can create view/query (or even better - SQL function) that will compute sum of ratings of 2 users, and sum like this may be used for many tasks if you think about it.




回答3:


If you use a left outer join you will get the records in the left table that DO NOT have a match in the right table. (As outlined here http://www.khankennels.com/blog/index.php/archives/2007/04/20/getting-joins/)

You can specify this join type via the third parameter of CodeIgniter's active record join() function.

Thus, try using something like:

$data = $this->db
             ->select('users.id,display_name,city,state,gender,users_pictures.picture')
             ->join('users_pictures','users_pictures.user_id = users.id')
             ->join('likes_dislikes', 'likes_dislikes.user_id = users.id', 'left outer')
             ->order_by('id','RANDOM')
             ->limit(1)
             ->where(array('users.approved'=>1,'users_pictures.approved'=>1))
             ->where(array('users.id !='=>$user_id))->get('users')->result_array();


来源:https://stackoverflow.com/questions/16680676/codeigniter-complex-join-only-if-rows-dont-exist

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!