推进 WHERE IN 子句和 MySQL 函数
Propel WHERE IN clause and MySQL function
最近我开始使用 Symfony 和 Propel 2.x 进行编码,但我遇到了 WHERE IN 子句的问题。
我想获得 1993 年和 1988 年出生的客户。
所以我写了这个 Propel 查询代码片段:
$query = ClientQuery::create()
->where('YEAR(Client.Birthdate) IN ?', [1993, 1988])
->find();
...并且 ORM 将这些整数映射为 DateTime 对象,因此最终查询如下所示:
SELECT clients.id, clients.user_id, clients.first_name, clients.last_name, clients.birthdate, clients.document_id, clients.street, clients.postal_code, clients.city, clients.country
FROM clients
WHERE YEAR(clients.birthdate) IN ('1970-01-01','1970-01-01')
是否可以在不使用 RAW SQL 查询的情况下使用 Propel 构建如下查询?
SELECT clients.id, clients.user_id, clients.first_name, clients.last_name, clients.birthdate, clients.document_id, clients.street, clients.postal_code, clients.city, clients.country
FROM clients
WHERE YEAR(clients.birthdate) IN (1993, 1988)
我尝试使用别名将 YEAR(clients.birthdate)
添加到 SELECT,但我也无法获得预期的查询。
您可以尝试指定绑定类型:
->where('YEAR(Client.Birthdate) IN ?', [1993, 1988], PDO::PARAM_INT)
编辑:
是的,你是对的。此解决方案将导致 PropelException,因为 Propel/PDO 无法将数组绑定到 int。
或者您可以使用 OR 条件:
$years = [1993, 1988];
// Get the key of the first element
$firstKey = key($years);
$query = ClientQuery::create();
foreach ($years as $key => $year) {
// Add _or() call for all elements except the first one
if ($key !== $firstKey) {
$query->_or();
}
// Add where condition and binding type
$query->where('YEAR(Client.Birthdate) = ?', $year, PDO::PARAM_INT);
}
$query = $query->find();
我同意这个解决方案看起来不太好,但它确实有效。
是的,看来您将不得不使用 4 个条件:
- 生日 >= '1993-01-01' AND 生日 < '1994-01-01'
- OR 生日 >= '1988-01-01' AND 生日 < '1989-01-01'
您可以使用 ClientQuery
class 的 condition()
和 combine()
方法来完成此操作。
http://propelorm.org/Propel/reference/model-criteria.html#combining-several-conditions
我建议不要使用 _or()
方法。
此外,我敢打赌使用 unix 时间戳会使您的应用程序逻辑更容易构建查询。
最近我开始使用 Symfony 和 Propel 2.x 进行编码,但我遇到了 WHERE IN 子句的问题。
我想获得 1993 年和 1988 年出生的客户。
所以我写了这个 Propel 查询代码片段:
$query = ClientQuery::create()
->where('YEAR(Client.Birthdate) IN ?', [1993, 1988])
->find();
...并且 ORM 将这些整数映射为 DateTime 对象,因此最终查询如下所示:
SELECT clients.id, clients.user_id, clients.first_name, clients.last_name, clients.birthdate, clients.document_id, clients.street, clients.postal_code, clients.city, clients.country
FROM clients
WHERE YEAR(clients.birthdate) IN ('1970-01-01','1970-01-01')
是否可以在不使用 RAW SQL 查询的情况下使用 Propel 构建如下查询?
SELECT clients.id, clients.user_id, clients.first_name, clients.last_name, clients.birthdate, clients.document_id, clients.street, clients.postal_code, clients.city, clients.country
FROM clients
WHERE YEAR(clients.birthdate) IN (1993, 1988)
我尝试使用别名将 YEAR(clients.birthdate)
添加到 SELECT,但我也无法获得预期的查询。
编辑:
是的,你是对的。此解决方案将导致 PropelException,因为 Propel/PDO 无法将数组绑定到 int。
或者您可以使用 OR 条件:
$years = [1993, 1988];
// Get the key of the first element
$firstKey = key($years);
$query = ClientQuery::create();
foreach ($years as $key => $year) {
// Add _or() call for all elements except the first one
if ($key !== $firstKey) {
$query->_or();
}
// Add where condition and binding type
$query->where('YEAR(Client.Birthdate) = ?', $year, PDO::PARAM_INT);
}
$query = $query->find();
我同意这个解决方案看起来不太好,但它确实有效。
是的,看来您将不得不使用 4 个条件:
- 生日 >= '1993-01-01' AND 生日 < '1994-01-01'
- OR 生日 >= '1988-01-01' AND 生日 < '1989-01-01'
您可以使用 ClientQuery
class 的 condition()
和 combine()
方法来完成此操作。
http://propelorm.org/Propel/reference/model-criteria.html#combining-several-conditions
我建议不要使用 _or()
方法。
此外,我敢打赌使用 unix 时间戳会使您的应用程序逻辑更容易构建查询。