CakePHP 4 搜索虚拟列

发布于 2025-01-18 01:30:56 字数 1293 浏览 3 评论 0原文

我们有一个cakephp 4.x应用程序,其中包含用户的表。数据库是Mariadb 10.7.3

用户具有名字(fname)和姓氏(lname)。这些在用户表中表示为2个单独的列。

因为我们想在应用程序的各个部分中输出一个用户的全名,所以我们在我们的查询中返回full_name condenates fname and lname lname 之间的空间。该代码看起来像这样:

// UsersController::index()
$usersQuery = $this->Users->find();

 $usersQuery->select([
    'full_name' => $usersQuery->func()->concat(['fname' => 'identifier', ' ', 'lname' => 'identifier']),
])
// ...

这在返回用户方面起作用,使得我们在结果集中获得full_name。我们可以将此数据输出到模板中。

但是,我们似乎无法在该虚拟列上搜索。我们有以下内容作为查询的一部分来执行搜索:

$usersQuery->where([
    'OR' => [
        'fname LIKE' => "%$searchTerm%",
        'lname LIKE' => "%$searchTerm%",
     ]
]);

这可以在fnamelname 独立上工作。如果用户被称为“ John Smith”,那么寻找“ John”将返回结果。搜索“史密斯”也将返回结果。但是,搜索全名“约翰·史密斯”,什么都没有。

我尝试添加:

'full_name LIKE' => "%$searchTerm%",

这个错误

sqlstate [42S22]:找不到列:1054未知列'full_name'where子句'

我可以在full_name上查询,如果没有,我该如何根据2列数据结构查询用户的fullName如第一段中所述?

我确实看到了一些有关此帖子的文章,但它们适用于CakePHP的较旧版本,对此无济于事。

We have a CakePHP 4.x application which contains a table of users. The database is MariaDB 10.7.3

Users have a first name (fname) and last name (lname). These are represented in the users table as 2 separate columns.

Because we want to output a user's full name in various parts of the application we return a full_name in our query which concatenates fname and lname with a space in between. The code looks like this:

// UsersController::index()
$usersQuery = $this->Users->find();

 $usersQuery->select([
    'full_name' => $usersQuery->func()->concat(['fname' => 'identifier', ' ', 'lname' => 'identifier']),
])
// ...

This works in terms of returning users such that we get full_name in the results set. We can output this data into templates.

But, we can't seem to search on that virtual column. We have the following as part of the query to perform a search:

$usersQuery->where([
    'OR' => [
        'fname LIKE' => "%$searchTerm%",
        'lname LIKE' => "%$searchTerm%",
     ]
]);

This works on fname and lname independently. If the user was called "John Smith" then searching for "John" would return a result. Searching for "Smith" would also return a result. But searching for the full name, "John Smith", doesn't return anything.

I tried adding:

'full_name LIKE' => "%$searchTerm%",

This errors with

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'full_name' in 'where clause'

Can I query on full_name and if not, how can I query a user's fullname based on a 2 column data structure as described in the first paragraph?

I did see some posts about this but they are for older versions of CakePHP and did not help with this.

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

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

发布评论

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

评论(1

爱你是孤单的心事 2025-01-25 01:30:56

您不能在中参考子句在处理该子句时,它们不可用,这是DBMS的限制。

在您的条件下重复调用函数:

$usersQuery->where(function (
    \Cake\Database\Expression\QueryExpression $exp,
    \Cake\ORM\Query $query
) use ($searchTerm) {
    return $exp->or([
        'fname LIKE' => "%$searchTerm%",
        'lname LIKE' => "%$searchTerm%",
        $exp->like(
            $query->func()->concat([
                'fname' => 'identifier',
                ' ',
                'lname' => 'identifier'
            ]),
            "%$searchTerm%"
        ),
    ]);
});

或者,如果适用,请使用have()因此,请记住,在中,子句中 list list中均不是子句中的字段的能力,也不是MySQL/Mariadb特定的事情!):

$usersQuery->having([
    'OR' => [
        'fname LIKE' => "%$searchTerm%",
        'lname LIKE' => "%$searchTerm%",
        'full_name LIKE' => "%$searchTerm%",
    ],
]);

另请参阅

You cannot refer to aliases in the WHERE clause, at the time of processing that clause, they are not available, that's a limitation of the DBMS.

Either repeat the function call in your conditions:

$usersQuery->where(function (
    \Cake\Database\Expression\QueryExpression $exp,
    \Cake\ORM\Query $query
) use ($searchTerm) {
    return $exp->or([
        'fname LIKE' => "%$searchTerm%",
        'lname LIKE' => "%$searchTerm%",
        $exp->like(
            $query->func()->concat([
                'fname' => 'identifier',
                ' ',
                'lname' => 'identifier'
            ]),
            "%$searchTerm%"
        ),
    ]);
});

or, in case applicable, use having() (make sure that you understand the implications of moving conditions into the HAVING clause before doing so, and keep in mind that the ability to refer to fields in the HAVING clause that are neither in the GROUP BY list, nor are aggregates, is a MySQL/MariaDB specific thing!):

$usersQuery->having([
    'OR' => [
        'fname LIKE' => "%$searchTerm%",
        'lname LIKE' => "%$searchTerm%",
        'full_name LIKE' => "%$searchTerm%",
    ],
]);

See also

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