如何简化此查询?

时间:2013-10-13 20:38:04

标签: php codeigniter

如果您查看以下查询:

$query = $this->db
        ->select('*')
        ->from('sets')
        ->where('type', 'd')
        ->or_where('type', 'e')
        ->or_where('type', 'f')
        ->or_where('type', 'g')
        ->or_where('type', 'h')
        ->or_where('type', 'i')
        ->or_where('type', 'j')
        ->or_where('type', 'k')
        ->or_where('type', 'l')
        ->or_where('type', 'm')

                    ...

        ->or_where('type', 'x')
        ->or_where('type', 'y')
        ->or_where('type', 'z')
        ->order_by('date', 'asc');

    return $query->get()->result();

在'type'列中,我有'a'到'z'基本上我希望所有行减去带有a,b,c的行。我怎样才能以更优雅的方式写出来?

5 个答案:

答案 0 :(得分:4)

由于您希望“基本上所有行除了那些带有a,b或c的行”,您可以使用where_not_in指令:

$query = $this->db
    ->select('*')
    ->from('sets')
    ->where_not_in('type', array('a','b','c'))
    ->order_by('date', 'asc');

参见例如this answer(注意数组!)

更新

只是为了添加spice,是否使用where_inwhere_not_in的问题实际上并不那么简单(“只使用将生成最短/最简单的SQL的 “)。如果您有一个大表,并且您要查找的集合的基数很大,您在该字段上有一个索引,然后(取决于很多因素)执行否定搜索可能远远低于(显然)较大的搜索。

索引很擅长查找 中的内容,而不是其中的内容。所以你可能会觉得这样做很有帮助:

->where_in('type', array_diff(  // Where type is...
    range('a', 'z'),            // ...everything...
    array('a','b','c')          // EXCEPT a, b or c
))

// The above solution works also if you look for non-consecutive letters.

然后,MySQL可以执行20次非常快速的索引查找(d,e,f,...),而不是在可能慢的全表扫描上进行三次比较。根据您要查找的项目数量,索引,磁盘性能,表格大小以及(我是否忽略了天气?)天气,即使SQL更复杂,第二种方法也可能更快。

当您处于查询优化阶段时,肯定会有所了解。 不要只是去为每个列编制索引,因为你会在一些在线所谓的教程中看到建议 - 索引有时可能有害对于表演,按照定义过度索引总是如此。

答案 1 :(得分:3)

也许是这样的?

$query = $this->db
        ->select('*')
        ->from('sets')

        ->where_in('type', range('d','z'))

        ->order_by('date', 'asc');

    return $query->get()->result();

答案 2 :(得分:0)

select * from sets where type not in ('a','b','c')

答案 3 :(得分:0)

从d到z创建一个字符数组,如:

$chars = array('d', 'e'...., 'z');

现在,使用where_in这样的句子:

$rs = $this->db->select('')->where_in('type', $chars)->get('table');

答案 4 :(得分:0)

$this->db->where('type !=', 'a');
$this->db->where('type !=', 'b');
$this->db->where('type !=', 'c');
$this->db->order_by('date', 'asc');
$query = $this->db->get('sets');

这应该有用。

另请注意,在选择所有内容并使用GET时无需使用SELECT或FROM。