【问题标题】:subquery in codeigniter active recordcodeigniter 活动记录中的子查询
【发布时间】:2011-08-28 04:14:28
【问题描述】:
SELECT * FROM certs WHERE id NOT IN (SELECT id_cer FROM revokace);

如何在CodeIgniter活动记录中编写上面的select语句?

【问题讨论】:

    标签: codeigniter


    【解决方案1】:

    ->where() 支持将任何字符串传递给它,它会在查询中使用它。

    你可以试试这个:

    $this->db->select('*')->from('certs');
    $this->db->where('`id` NOT IN (SELECT `id_cer` FROM `revokace`)', NULL, FALSE);
    

    where() 中的 ,NULL,FALSE 告诉 CodeIgniter 不要逃避查询,这可能会搞砸。

    更新:你也可以看看我写的subquery library

    $this->db->select('*')->from('certs');
    $sub = $this->subquery->start_subquery('where_in');
    $sub->select('id_cer')->from('revokace');
    $this->subquery->end_subquery('id', FALSE);
    

    【讨论】:

    • CI 中的子查询至今仍不受支持?
    • @iMohammad:CI 中的子查询将永远得到官方支持。并非所有数据库都支持它; CI 适用于任何数据库。
    【解决方案2】:

    函数 _compile_select()_reset_select() 已弃用。
    而是使用get_compiled_select():

    #Create where clause
    $this->db->select('id_cer');
    $this->db->from('revokace');
    $where_clause = $this->db->get_compiled_select();
    
    #Create main query
    $this->db->select('*');
    $this->db->from('certs');
    $this->db->where("`id` NOT IN ($where_clause)", NULL, FALSE);
    

    【讨论】:

    • 我个人几乎更喜欢这个,因为我能够分割每个子查询并让它们安全地逃脱并在遵守后做好准备。
    • 它们在仍在使用的 codeigniter 2.7 中没有贬值。 Op 在 Codeigniter 3 之前的 2011 年提出了这个问题。如果您使用的是 codeigniter 2.7,那么@mattumotu 的答案是正确的。
    【解决方案3】:

    CodeIgniter Active Records 目前不支持子查询,但是我使用以下方法:

    #Create where clause
    $this->db->select('id_cer');
    $this->db->from('revokace');
    $where_clause = $this->db->_compile_select();
    $this->db->_reset_select();
    
    #Create main query
    $this->db->select('*');
    $this->db->from('certs');
    $this->db->where("`id` NOT IN ($where_clause)", NULL, FALSE);
    

    _compile_select() 和 _reset_select() 是两个未记录的 (AFAIK) 方法,它们编译查询并返回 sql(不运行它)并重置查询。

    在主查询中,where 子句中的 FALSE 告诉 codeigniter 不要转义查询(或添加反引号等),这会弄乱查询。 (NULL 只是因为 where 子句有一个我们没有使用的可选第二个参数)

    但是您应该知道,由于 _compile_select() 和 _reset_select() 没有记录在案的方法,因此功能(或存在)可能会在未来的版本中发生变化。

    【讨论】:

    • $this->db->_compile_select();已弃用,我相信 _reset_select() 也已弃用。这个答案是绝对的。
    • @Bandpay 是的,在经过测试查询后遗憾地意识到。
    • _compile_select() 未被弃用。由于未知的原因,从 CI 2.1.0 开始,它是一个受保护的函数(在 system/database/DB_active_rec.php 中),这意味着您不能使用它,除非您从函数声明中删除“受保护”子句(但始终是小心修改核心)。
    • 查看this answer 的相关问题,以获取 CI 的补充内容(而不是修改)。
    • 在 ExpressionEngine 2.7.3 中,EE 的核心是使用_compile_select。它的 CI 显然是 2.0.1 版。该方法用于 EE 2.7 本身引入的功能中,所以我想它暂时不会有任何进展,否则他们会想出一个解决方法(例如另一个答案中的 get_compiled_select 方法)。
    【解决方案4】:

    最初的问题可能有点晚,但对于未来的查询,这可能会有所帮助。 实现这一目标的最佳方法是 将内部查询的结果获取到这样的数组中

    $this->db->select('id');
    $result = $this->db->get('your_table');
    return  $result->result_array();
    

    然后在下面的活动记录子句中使用比数组

    $this->db->where_not_in('id_of_another_table', 'previously_returned_array');
    

    希望对你有帮助

    【讨论】:

    • 我认为这个解决方案的问题是它需要两次调用数据库,而子查询只需要一次。
    • 我同意。但我发现这更具可读性。如果由于触发了额外的查询而没有显着影响性能,我更喜欢这种方法而不是编写可能涉及其自身缺陷的子查询
    • 我不会在我的一个项目中使用它。如果可以一次完成工作,则无需两次访问数据库。不应向寻求优雅/专业解决方案的研究人员推广此技术。
    【解决方案5】:

    以简单的方式喜欢这个。

        $this->db->select('*');
        $this->db->from('certs');
        $this->db->where('certs.id NOT IN (SELECT id_cer FROM revokace)');
    
        return $this->db->get()->result();
    

    【讨论】:

      【解决方案6】:

      查询:SELECT * FROM (SELECT id, product FROM product) as product可以使用:

      $sub_query_from = '(SELECT id, product FROM product ) as product';
      $this->db->select();
      $this->db->from($sub_query_from);
      $query = $this->db->get()
      

      请注意,在 sub_query_from 字符串中,... product ) as... 之间必须使用空格

      【讨论】:

      • 这看起来不像子查询,更像是字符串查询?
      • 这个答案并没有完全理解 CI 的查询构建工具包。较早的答案展示了卓越的技术。此页面没有新值。
      • 此查询将不起作用,因为您没有正确的查询,并且在子查询中您必须添加表并且无论如何您都没有子查询。
      【解决方案7】:

      我认为这段代码会起作用。我不知道这是否是 CI 中可接受的查询样式,但它在我之前的问题中完美运行。 :)

      $subquery = 'SELECT id_cer FROM revokace';
      
      $this->db->select('*');
      $this->db->where_not_in(id, $subquery);
      $this->db->from('certs');
      $query = $this->db->get();
      

      【讨论】:

      • 这只是“半活动记录”。较早的帖子演示了如何完全实现活动记录语法。这个迟到的答案并没有给这个页面带来新的价值。
      【解决方案8】:
      $this->db->where('`id` IN (SELECT `someId` FROM `anotherTable` WHERE `someCondition`='condition')', NULL, FALSE);
      

      来源:http://www.247techblog.com/use-write-sub-queries-codeigniter-active-records-condition-full-explaination/

      【讨论】:

      • 这个答案没有完全实现 CI 的可用方法来构建查询。较早发布的答案提供了比这篇文章更好的建议。此页面没有新价值。此外,未加载超链接,因此这是仅代码的答案。对这个页面或研究人员没有价值。
      【解决方案9】:
          $where.= '(';
          $where.= 'admin_trek.trek='."%$search%".'  AND ';
          $where.= 'admin_trek.state_id='."$search".'  OR ';
          $where.= 'admin_trek.difficulty='."$search".' OR ';
          $where.= 'admin_trek.month='."$search".'  AND ';
          $where.= 'admin_trek.status = 1)';
      
          $this->db->select('*');
          $this->db->from('admin_trek');
          $this->db->join('admin_difficulty',admin_difficulty.difficulty_id = admin_trek.difficulty');
          $this->db->where($where); 
          $query = $this->db->get();
      

      【讨论】:

      • 这个仅代码的答案与所提出的问题完全没有关联。充其量,这是对另一个问题的正确答案。老实说,这个 sn-p 并没有完全理解 CI 的活动记录提供的可用方法。页面没有价值。
      猜你喜欢
      • 2016-03-10
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-08
      相关资源
      最近更新 更多