【问题标题】:Codeigniter active record join with 3 tablesCodeigniter 活动记录加入 3 个表
【发布时间】:2012-11-17 19:06:31
【问题描述】:

我有 3 张桌子,

user - contains user_id | username | fullname | email etcc
user_profile - contains entry_id |user_id| profile_image_id| user_location etcc
user_profile_images - contains image_id| user_id | file_path | file_thumb | date etcc

当一个用户注册时,所有的细节都进入到用户表中,user_id 也被添加到 user_profile 表中,其余的设置默认为 NULL,直到用户添加一些配置文件信息。

我在 model_users 中有一个查询来从这三个表中获取所有用户的数据,它是这样的;

$this->db->where('users.user_id', $user_id)->select('*')->from('users');
$this->db->join('user_profile', 'user_profile.user_id = users.user_id', 'left');
$this->db->join('user_profile_images','user_profile_images.image_id = user_profile.profile_image_id','left');

只有当 user_profile 中的 profile_image_id 字段不为空时,即用户上传了图片时,它才能正常工作。在该字段为空的情况下,即使返回所有其他数据,也不返回用户user_id。

我知道为什么会这样,因为我的联接查询需要字段 profile_image_id 但目前我的解决方法是将 user_profile 中的 profile_image_id 设置为 1(默认),这是默认图像,并且 image_id 为 1 和 user_id 0 因为它是一般的默认图像。但我仍然无法克服这样一个事实,即我需要更新该查询以使其不再是黑客攻击。 你们有什么想法吗?

【问题讨论】:

  • 尝试将 user_profile_images 加入更改为“正确”加入?
  • 感谢回复,还是不行:(
  • 最好的办法是关闭这个问题,将查询转换为原始 MySQL 查询,然后在 SO 上发布该查询。这里有很多 mySQL 专家 - 但我怀疑他们会以当前格式知道这个问题的答案。
  • 只是不要使用 left 并将这个 user_profile_images.image_id = user_profile.profile_image_id 改为这个 user_profile.profile_image_id = user_profile_images.image_id 然后检查你是否也设置了索引
  • @Ispuk 为什么左连接会成为问题?实际上,左连接通常会获得最快的连接语法性能。

标签: mysql codeigniter activerecord codeigniter-2


【解决方案1】:

试试

$this->db->select('*')->select('users.user_id')->from('users')
                ->join('user_profile', 'user_profile.user_id = users.user_id', 'LEFT')
                ->join('user_profile_images', 'user_profile_images.image_id = user_profile.profile_image_id', 'LEFT')
                ->group_by('users.user_id')
                ->where('users.user_id', $user_id);
                $query = $this->db->get();

【讨论】:

    【解决方案2】:

    对表使用联接时,您需要所有联接表中的列具有唯一名称。您可以通过 AS 语法添加列别名,或者只检索您需要的列。在您的情况下,错误很可能是由于所有三个表中都存在user_id。因此,结果就像你所经历的那样。 user_id 仅在最后一次出现时检索,即如果您的用户已上传图像。我会像这样改变查询:

    $this->db->where('users.user_id', $user_id);
    $this->db->select('users.*,user_profile.user_location,user_profile_images.filepath'); // and other fields of interest...
    $this->db->from('users');
    $this->db->group_by('users.user_id'); // very useful for not getting multiple rows/user
    $this->db->join('user_profile', 'user_profile.user_id = users.user_id', 'left');
    $this->db->join('user_profile_images','user_profile_images.image_id = user_profile.profile_image_id','left'); 
    

    【讨论】:

    • 感谢 jtheman,它们有很多字段,所以我无法手动选择它们 :( 同时我使用了双选(->select('*')- >select('users.user_id') )。哪个有效,但您认为这是一种好的编码习惯吗?
    • 双选没问题,但是你可以用逗号把它放在一个中(select(',users.user_id'))。我不会在''上进行选择,因为它返回重复的列......
    【解决方案3】:

    试试这个。

     $this->db->select("*");
                $this->db->from('table1');
                $this->db->join('table2','table2.id1=table1.id1');
                $this->db->join('table3','table3.id1=table1.id1');
                $query = $this->db->get();
                return $query->result();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      相关资源
      最近更新 更多