使用 CodeIgniter 活动记录查询对 WHERE 子句逻辑进行分组

发布于 2024-09-15 03:33:31 字数 624 浏览 4 评论 0原文

我在 sql 查询中使用几个“like”时遇到了问题(使用 Codeigniter 的 activerecord 生成):

SELECT *
FROM (`posts`)
WHERE
    `city` LIKE '%test%'
    AND `title` LIKE '%%'
    OR `text` LIKE '%%'

事情是,它似乎读取此查询,就好像第一个 like 和第二个 like 周围有括号一样,但我希望在第二个和最后一个周围有一个括号(我希望它比较最后一个或倒数第二个是否有效)。

如何使用 Codeigniter 的 Active Record 类实现此目的?

当前代码:

if($type != 0)
    $this->db->where('type', $type);
    
$this->db->like('city', $area);
$this->db->like('title', $words);
$this->db->or_like('text', $words);
    
return $this->db->get('posts')->result_array(); 

I've run into a problem using several "like" in my sql-query (generated with Codeigniter's activerecord):

SELECT *
FROM (`posts`)
WHERE
    `city` LIKE '%test%'
    AND `title` LIKE '%%'
    OR `text` LIKE '%%'

Thing is, it appears to read this query as if there was a parenthesis around the first like and the second like, but I want there to be a parenthesis around the second and the last like (I want it to compare if the last or the next to last works).

How can I achieve this using Codeigniter's Active Record class?

Current code:

if($type != 0)
    $this->db->where('type', $type);
    
$this->db->like('city', $area);
$this->db->like('title', $words);
$this->db->or_like('text', $words);
    
return $this->db->get('posts')->result_array(); 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

人海汹涌 2024-09-22 03:33:31

musoNic80的答案是正确的。我想补充以下内容。

在Codeigniter中总体支持以下内容。

$this->db->like();
$this->db->or_like();
$this->db->not_like();
$this->db->or_not_like();

希望这会对某人有所帮助。

musoNic80's answer is correct. I would like to add the following.

In Codeigniter supporting the following overall.

$this->db->like();
$this->db->or_like();
$this->db->not_like();
$this->db->or_not_like();

Hope this will help someone.

鲜肉鲜肉永远不皱 2024-09-22 03:33:31

我认为 CI 没有添加任何括号。它将在前两个语句之间添加“AND”,并在后两个语句之间添加“OR”。为了实现你想要的,我会写我自己的声明。这非常简单。

$sql = SELECT * FROM 'posts' WHERE city LIKE ? AND ( title LIKE ? OR text LIKE ? );
$query = $this->db->query($sql, array($area, $words, $words));

请注意我是如何使用绑定的。这会自动为您转义字符。

I don't think CI is adding any paranthesis. It will add an 'AND' between the first two statements and an 'OR' between the last two. To achieve what you want, I would write my own statement. It's very straightforward.

$sql = SELECT * FROM 'posts' WHERE city LIKE ? AND ( title LIKE ? OR text LIKE ? );
$query = $this->db->query($sql, array($area, $words, $words));

Notice how I've used binding. This automatically escapes characters for you.

硪扪都還晓 2024-09-22 03:33:31

这就能解决问题

$this->db->select('*')->from('my_table')
        ->group_start()
                ->where('a', 'a')
                ->or_group_start()
                        ->where('b', 'b')
                        ->where('c', 'c')
                ->group_end()
        ->group_end()
        ->where('d', 'd')
->get();

// Generates:
// SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd'

this will do the trick

$this->db->select('*')->from('my_table')
        ->group_start()
                ->where('a', 'a')
                ->or_group_start()
                        ->where('b', 'b')
                        ->where('c', 'c')
                ->group_end()
        ->group_end()
        ->where('d', 'd')
->get();

// Generates:
// SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd'
梦境 2024-09-22 03:33:31

要封装条件逻辑,请在条件构建方法调用周围使用 group_start()group_end() 方法。

要构建使用 AND 连接到子句其余部分的封装条件集,请使用 group_start(),对于 OR 使用 or_group_start( )

此外,like()not_like()or_like()or_not_like() 都具有此功能接收关联数组作为第一个参数 - 这些包装器迭代调用受保护的方法 _like() 并使用 OR 连接条件(如果包装器名称进行了描述),否则AND

if ($type) {
    $this->db->where('type', $type);
}
    
return $this->db
    ->like('city', $area)
    ->group_start()
         ->or_like([
             'title' => $words,
             'text' => $words
         ])
    ->group_end()
    ->get('posts')
    ->result_array();

根据数据库方言/驱动程序,引用可能有所不同,但呈现的查询将类似于以下内容:

SELECT * 
FROM `posts`
WHERE `type` = 1
AND `city` LIKE '%some city%' ESCAPE '!'
AND (
    `title` LIKE '%term%' ESCAPE '!'
    OR `text` LIKE '%term%' ESCAPE '!'
)

To encapsulate conditional logic, use group_start() and group_end() methods around condition building method calls.

To build an encapsulated set of conditions joined to the rest of the clause with AND use group_start(), for OR use or_group_start().

Also, like(), not_like(), or_like(), and or_not_like() all have the ability to receive an associative array as the first parameter -- these wrappers make iterated calls of the protected method _like() and join the conditions with OR if described by the wrapper name, otherwise AND.

if ($type) {
    $this->db->where('type', $type);
}
    
return $this->db
    ->like('city', $area)
    ->group_start()
         ->or_like([
             'title' => $words,
             'text' => $words
         ])
    ->group_end()
    ->get('posts')
    ->result_array();

Depending on database dialect/driver, quoting may differ, but the rendered query will resemble this:

SELECT * 
FROM `posts`
WHERE `type` = 1
AND `city` LIKE '%some city%' ESCAPE '!'
AND (
    `title` LIKE '%term%' ESCAPE '!'
    OR `text` LIKE '%term%' ESCAPE '!'
)
眼眸里的快感 2024-09-22 03:33:31

当您必须使用表连接时,请尝试以下方法

public function get_all_airports($para) {

        $this->db->select('airports.name as air_name, airports.city, airports.type, airports.home_link, country.name as con_name');
        $this->db->from('airports');

        $this->db->join('country', 'airports.iso_country = country.code', 'inner');

        $this->db->where("airports.type !=", "small_airport");
        $this->db->where("airports.type !=", "closed");
        $this->db->where("airports.type !=", "heliport");
        $this->db->where("airports.type !=", "medium_airport");
        $this->db->where("airports.type !=", "seaplane_base");

        $where = "(country.name LIKE '%$para%' OR airports.city LIKE '%$para%')";
        $this->db->where($where);

        echo json_encode($this->db->limit(20)->get()->result());
    }

when you have to use table join as well try following method

public function get_all_airports($para) {

        $this->db->select('airports.name as air_name, airports.city, airports.type, airports.home_link, country.name as con_name');
        $this->db->from('airports');

        $this->db->join('country', 'airports.iso_country = country.code', 'inner');

        $this->db->where("airports.type !=", "small_airport");
        $this->db->where("airports.type !=", "closed");
        $this->db->where("airports.type !=", "heliport");
        $this->db->where("airports.type !=", "medium_airport");
        $this->db->where("airports.type !=", "seaplane_base");

        $where = "(country.name LIKE '%$para%' OR airports.city LIKE '%$para%')";
        $this->db->where($where);

        echo json_encode($this->db->limit(20)->get()->result());
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文