推进 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 时间戳会使您的应用程序逻辑更容易构建查询。