在 WHERE 子句中使用 AND 和 OR 条件组合构建 CodeIgniter

问题描述 投票:0回答:10

我想在 CI 中组合 AND OR mysql 查询。我已经看过这个论坛帖子,但他们没有提供我需要的确切解决方案。

如何严格使用 CI 框架创建以下查询? (我可以在没有括号的情况下轻松创建查询,但它不是同一个查询。)

SELECT *
FROM `Persons`
WHERE
    LastName='Svendson'
    AND Age="12"
    AND (
         FirstName='Tove'
         OR FirstName='Ola'
         OR Gender="M"
         OR Country="India"
    ) 

P.S.:这只是一个示例查询,即使它没有意义,也不建议将查询的整个 OR 部分写在单个

where()
中。

编辑:基本上我想要实现以下简单查询:

SELECT *
FROM `table`
WHERE field1='value1' AND (field2='value2' OR field3='value3')

我目前正在运行 CI2。

php mysql codeigniter query-builder logical-grouping
10个回答
54
投票

在 CodeIgniter 3 中,有新方法 group_start() 和 group_end() 正是用于此目的。

return $this->db
     ->where('LastName', 'Svendson');
     ->where('Age', 12);
     ->group_start()
         ->where('FirstName','Tove')
         ->or_where('FirstName','Ola')
         ->or_where('Gender','M')
         ->or_where('Country','India')
     ->group_end()
     ->get('Persons')
     ->result();

48
投票

这会起作用吗?

$this->db->where('LastName', 'Svendson');
$this->db->where('Age', 12);
$this->db->where("(FirstName='Tove' OR FirstName='Ola' OR Gender='M' OR Country='India')", NULL, FALSE);
$query = $this->db->get('Persons');
return $query->result();

4
投票

使用codeigniter 3.0框架,有新功能可用于单独或where和where操作。即group by和group end

代码如下,

$this->db->where('LastName', 'Svendson');
$this->db->where('Age', 12);
$this->db->group_start();
$this->db->or_where('FirstName','Tove');
$this->db->or_where('FirstName','Ola');
$this->db->or_where('Gender','M');
$this->db->or_where('Country','India');
$this->db->group_end();
$query = $this->db->get('Persons');
return $query->result();

3
投票

你可以简单地使用这个

$this->db->where("status","live")->or_where("status","dead");

你也可以使用

$this->db->where("(status='live' OR status='dead')");

3
投票

在Codeigniter中我们可以这样使用,很容易理解。

$sql = "SELECT
            *
        FROM
            `Persons`
        WHERE
            LastName = 'Svendson'
        AND Age = '12'
        AND (
            FirstName = 'Tove'
            OR FirstName = 'Ola'
            OR Gender = 'M'
            OR Country = 'India'
        )";

$query = $this->db->query($sql);

return $query->result();


1
投票

目前使用 CI2,如果不扩展数据库类并将方法的访问类型从私有更改为公共/受保护,则无法访问数据库类的查询生成器方法($this->db->_compile_select()),这会杀死构建子查询的能力就像您尝试使用 ActiveRecord 类构建一样。 制作像您尝试构建的子查询这样的子查询的唯一方法是仅使用数据库查询方法

$table = $this->db->dbprefix('tablename');

$sql = "SELECT * FROM `{$table}` WHERE field1='?' AND (field2='?' OR field3='?') ";
$this->db->query($sql,array($field1,$field2,$field3));  

CI Subquerys 上有一篇关于执行此操作的博客文章,但它已经过时并且仅适用于 CI 1.7 希望这会有所帮助。


0
投票

我需要 CodeIgniter 2 的这个,但我需要仍然转义的值,所以 csotelo 的答案对我来说不好,我不想像 Shawn C 的答案那样重写整个查询,所以我最终这样做了:

$this->db->where('LastName', $lastName);
$this->db->where('Age', $age, false);
$this->db->where('1 AND ( 0', null, false); // This one starts the group
  $this->db->or_where('FirstName', $firstName1);
  $this->db->or_where('FirstName', $firstName2);
  $this->db->or_where('Gender', $gender);
  $this->db->or_where('Country', $country);
$this->db->or_where('0 )', null, false); // This one ends the group
$query = $this->db->get('Persons');

这会生成以下查询:

SELECT *
FROM (`Persons`)
WHERE `LastName` =  'Svendson'
AND Age = 12
AND 1 AND ( 0 -- This one starts the group
OR `FirstName` =  'Tove'
OR `FirstName` =  'Ola'
OR `Gender` =  'M'
OR `Country` =  'India'
OR 0 ) -- This one ends the group

与此相同:

SELECT * FROM (`Persons`) WHERE
`LastName` = 'Svendson' AND Age = 12 AND 1 AND
(0 OR `FirstName` = 'Tove' OR `FirstName` = 'Ola' OR `Gender` = 'M' OR `Country` = 'India' OR 0)

0
投票
  • 批量
    OR
    条件必须用括号封装以保留逻辑。 在填充这些条件的查询构建器方法的两侧使用
    group_start()
    group_end()
  • 检查同一列上是否相等的多个
    OR
    条件可以合并为一个
    IN
    条件。
  • 如果所有
    OR
    条件位于不同的列上,您只需将关联数组传递给
    or_where()
    即可,而无需在分组包装器内调用任何其他方法。
  • get_where()
    是一个方便的函数来指定表,包含
    AND WHERE
    条件,并执行构建的查询。
return $this->db
    ->group_start()
        ->where_in('FirstName', ['Tove', 'Ola'])
        ->or_where(['Gender' => 'M', 'Country' => 'India'])
    ->group_end()
    ->get_where('Persons', ['LastName' => 'Svendson', 'Age' => 12])
    ->result();

构建 SQL 将类似于此(我调整了间距;您的数据库方言/设置可能会影响引用):

SELECT *
FROM `Persons`
WHERE (
    `FirstName` IN ('Tove', 'Ola')
    OR `Gender` = 'M'
    OR `Country` = 'India'
)
AND `LastName` = 'Svendson'
AND `Age` = 12

-3
投票

查询本身没有意义,您正在选择:

  • 托夫·斯文森,12 岁
  • 奥拉·斯文森,12 岁
  • 任何名为 Svendson 的 12 岁男性
  • 任何来自印度、名叫 Svendson、12 岁的人

Tove 看起来像一个男人的名字,所以不需要选择性别。 Ola 看起来像是一个女孩的名字,所以选择性别不仅没有必要,而且没有意义。您的查询将返回任何名为 Svendson 的 12 岁男性、任何来自印度、名为 Svenson 的 12 岁男孩,以及 Tove 和 Ola Svendson(如果他们是 12 岁)。

为什么不想将其放在 () 括号之间?出于某种原因你想用活动记录来完成它吗?

© www.soinside.com 2019 - 2024. All rights reserved.