2013-05-21 45 views
0

我正在制作一个约会应用程序,很像tindler。用户可以喜欢或不喜欢其他用户,如果两个用户都喜欢对方,他们可以选择与对方聊天。目前正在建设的查询随意拉一个随机分布和他们的照片之一:codeigniter复合只有在行不存在的情况下才会连接

$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();  

现在,这里就是我很困惑。我有一个表,它由USER_ID,foreign_user_id和EVENT_TYPE(的likes_dislikes像,不喜欢)。

如果您不喜欢或已经喜欢用户,我不希望他们出现在我的结果中。我能想到的处理这个问题的唯一方法是执行第二个查询来检查这个问题,然后再做一个“随机”查询,如果你已经喜欢/不喜欢它们,那么你只会看到你还没有评价过的用户。有没有更好的办法?

任何帮助是非常赞赏:)

回答

1

你听说过EXISTSNOT EXISTSMySQL命令?后者是你应该尝试的。

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 
) 

以上将列出所有用户,不包括所有喜欢/不喜欢的用户。试图用Codeigniter来形成这个SQL声明而没有绑定这个值,这是有点冒险的。

通过谷歌的简短调查(可能现在已经过时)表明,以下应是合适的。

//...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); 

注意到最后一部分AND 1 = ", 1);

+0

这对我来说非常合适,但你的回答激励我朝着正确的方向前进。我能够发现以下工作完美无缺: - > where('NOT EXISTS(SELECT 1 FROM users_likes_dislikes ld WHERE ld.foreign_user_id = users.id AND ld.user_id ='。$ this-> user_id。')' ,'',FALSE) – skrilled

+0

非常感谢你的帮助:) – skrilled

1

这不是一个答案,但我有一点建议。

可以更改喜欢/不喜欢为数字,-1(不喜欢),0或NULL(未分级),1(等)构成。

它应该简化/缩短您的查询。

在此之后 - 你可以创建视图/查询(甚至更好 - SQL函数)将计算2个的用户评级的总和,总结这样,如果你认为它可以用于许多任务。

+0

这对计算就像流行的东西,使用户可以看到他们的个人资料是如何做的还是等数据一个伟大的想法,但亚不会解决,确保用户的问题看不到,他们已经投票人。 upvote,因为我喜欢你的想法。 – skrilled

+0

我认为这也可能有助于这种过滤。要过滤他们已经投票的配置文件,您可以将该数字与0进行比较。这将帮助您摆脱应用程序中的一些“IS NULL”语句。 – Kamil

+0

还有一件事 - 尽量使用数据库视图和SQL存储过程。在CI中编写复杂的查询并不舒服。 – Kamil

0

如果使用左外连接,你会得到左表中的记录没有右表的匹配。 (如这里http://www.khankennels.com/blog/index.php/archives/2007/04/20/getting-joins/概述)

您可以指定这个通过CodeIgniter的活动记录的第三个参数加入连接类型()函数。

因此,尝试使用类似:

$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(); 
+0

这似乎是一个合理的想法,但它仍然返回有一个现有的行,结束了使用不存在的功能,这很好。非常感谢你的帮助:) – skrilled

相关问题