CakePHP 3 - 在自定义查找器中使用 IN...SELECT

CakePHP 3 - using IN...SELECT in a custom finder

我写了一个custom finder方法如下:

public function findSubstanceListNotifications(Query $query, array $options)
{
    $date_start = $options['date_start'];
    $date_end = $options['date_end'];
    $list_id = $options['list_id'];

    $list_substances = TableRegistry::getTableLocator()->get('TblListsSubstances')->find()
            ->select('substance_id')->where(['list_id IN' => $list_id])->enableHydration(false);

    if ($list_substances->isEmpty()) {
        return false;
    }

    $query = $this->find()
            ->select(['RevisionSubstances.date', 'RevisionSubstances.comment', 'RevisionSubstances.id', 'Substances.name', 'Substances.app_id'])
            ->where(['substance_id IN' => array_column($list_substances->toArray(), 'substance_id')]);

    $query->where(['RevisionSubstances.date >=' => $date_start, 'RevisionSubstances.date <=' => $date_end]);

    $query->contain('Substances');
    $query->order(['RevisionSubstances.date' => 'DESC', 'Substances.app_id' => 'ASC']);

    $query->enableHydration(false);

    if ($query->isEmpty()) {
        return false;
    }

    return $query;
}

由于执行此操作时达到内存限制,我收到 PHP 致命错误。

我怀疑,原因是 substance_id IN 条件使用了一个有几千个键的数组。

有没有一种替代的方式来写这个,而不是使用 IN 后跟一个数组,我可以在这一点上写 SELECT 语句?类似于 MySQL.

中的子查询

条件的 SQL 由 $list_substances 描述,但本质上是:

SELECT substance_id FROM tbl_lists_substances WHERE list_id IN(1,2,3,4);

上面的 IN() 条件使用与登录用户相关的 ID。然而,这个数组最多只有不到 20 个键,所以我认为这里不会有任何类似的内存问题。但是我也需要知道如何在 运行 子查询时访问这些。

蛋糕PHP版本是3.7

我读过有关在 docs 中使用 newExpr() 的信息,但目前看不到如何以可行的方式注入 SELECT 语句。

几千个密钥很容易就太多了。我不确定您对子查询的担忧是什么,但它应该可以正常工作,只需将 $list_substances 作为条件传递,例如:

->where(['substance_id IN' => $list_substances])