2011-05-18 305 views

回答

72

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

您可以尝试使用此:

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

,NULL,FALSEwhere()告诉笨不要逃避查询,这可能搞砸了。

UPDATE:您也可以查看我写的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); 
+0

子查询在CI仍然不支持多达这个日期? – Sobiaholic 2013-07-18 12:07:48

+11

@iMohammad:CI中的子查询将永远不会被官方支持。并非所有数据库都支持它; CI旨在用于任何数据库。 – 2013-07-18 13:26:16

+0

哦!以前从来不知道。感谢您的回答。 – Sobiaholic 2013-07-18 13:28:07

13

笨的活动记录当前不支持子查询,但我用下面的办法:

#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()是两个无证(据我所知)方法,该编译查询并返回SQL(不运行它)并重置查询。

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

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

+5

$ this-> db - > _ compile_select();已弃用,我相信_reset_select()也被弃用。这个答案是绝对的。 – 2012-01-14 15:36:40

+0

@Bandpay在测试过的查询后很遗憾地意识到。 – motto 2012-02-10 17:25:40

+1

'_compile_select()'不被弃用。由于不明原因,从CI 2.1.0开始,它是一个受保护的函数(在system/database/DB_active_rec.php中),这意味着除非从函数声明中删除“protected”子句,否则不能使用它警惕修改核心)。 – pbarney 2013-11-07 00:32:05

1

对原始问题可能有点晚,但对未来的查询可能有所帮助。实现这一 最好的办法是 获取内部查询的结果是这样

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

希望这有助于

+4

我认为这个解决方案的问题是它需要两次调用数据库,而一个子查询只需要一次。 – eelkedev 2012-11-24 12:48:23

+0

我同意。但我觉得这更可读。如果由于额外查询被解雇而没有显着的性能影响,我宁愿采用这种方法,而不是编写可能涉及其自身陷阱的子查询 – 2012-11-27 13:09:57

32

不建议使用功能_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); 
+1

我个人更喜欢这样做,因为我能够对每个子查询进行细分并使其安全地逃脱&一旦编写完成准备。 – MackieeE 2015-10-27 14:51:50

+0

我也喜欢这个 – plonknimbuzz 2016-11-24 06:52:56

+0

它们不会在仍在使用的codeigniter 2.7中折旧。 Op于2011年在Codeigniter 3之前提出了这个问题。如果您使用的是codeigniter 2.7,那么@mattumotu的答案是正确的。 – PrestonDocks 2018-01-31 08:00:36

2

对于查询: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...

+0

它不适用于CI 3.x不是吗? – Dimas 2015-05-28 12:10:58

+0

这不看起来像一个子查询,但更像是一个字符串查询? – killstreet 2016-01-15 14:19:15

0

我认为这段代码会起作用。我不知道在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(); 
0
$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();