0

如果您查看以下查询:

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

在“类型”列中,我基本上有“a”到“z”,我希望所有行都减去带有 a、b、c 的行。我怎样才能以更优雅的方式写这个?

4

5 回答 5

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

例如看这个答案(当心数组!)

更新

只是为了增加趣味,是否使用的问题where_in实际上where_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、...),而不是在可能很慢的全表扫描中只进行 3 次比较。根据您要查找的项目数量、索引、磁盘性能、表大小和(我是否忽略了天气?)天气,即使 SQL 更复杂,第二种方法也可能更快。

当您处于查询优化阶段时,这肯定是值得关注的。不要像在一些在线所谓的教程中所建议的那样只去索引每一列——索引有时会对性能有害,而根据定义过度索引总是如此。

于 2013-10-13T20:41:28.103 回答
3

也许是这样的?

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

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

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

    return $query->get()->result();
于 2013-10-13T20:43:23.317 回答
0
select * from sets where type not in ('a','b','c')
于 2013-10-13T20:41:14.740 回答
0

制作一个从 d 到 z 的字符数组,例如:

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

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

$rs = $this->db->select('')->where_in('type', $chars)->get('table');
于 2013-10-13T20:42:24.263 回答
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。

于 2013-10-13T20:46:22.510 回答