ORM中的多次计数不起作用

时间:2016-04-16 17:15:06

标签: cakephp cakephp-3.2

我想根据不同的时间计算租约数

    $start_date = $end_date = $end_date1 = new \DateTime('first day of last month');

    $start_date = $start_date->format('Y-m-01 00:00:00');
    $end_date = $end_date->format('Y-m-t 23:59:59');
    $end_date1 = $end_date1->format('Y-m-'. date('d') .' 23:59:59');

    $start_date2 = $end_date2 = new \DateTime('now');
    $start_date2 = $start_date2->format('Y-m-01 00:00:00');
    $end_date2 = $end_date2->format('Y-m-d 23:59:59');

   $tenancyDetails = $this
        ->find()
        ->select([ 
            'total_last_month' => $this->find()->func()->count('Tenancy.id'),
            'count_last_month' => $this->find()->func()->count('Tenancy1.id'),
            'count_curr_month' => $this->find()->func()->count('Tenancy2.id'),
            'Tenancy.created', 'Tenancy1.created', 'Tenancy2.created',
        ])            
        ->leftJoin(['Tenancy1' => 'tenancy'],[
            'Tenancy1.active' => 1,
            'Tenancy1.stage !=' => 1,
            'Tenancy1.company_id' => $id,
        ])
        ->leftJoin(['Tenancy2' => 'tenancy'],[
            'Tenancy2.active' => 1,
            'Tenancy2.stage !=' => 1,
            'Tenancy2.company_id' => $id,
        ])
        ->where([
            'Tenancy.active' => 1,
            'Tenancy.stage !=' => 1,
            'Tenancy.company_id' => $id,
        ])
       ->where(function ($exp, $q) use ($start_date, $end_date) {
            return $exp->between('Tenancy.created', $start_date, $end_date);
        })
       ->where(function ($exp, $q) use ($start_date, $end_date1) {
            return $exp->between('Tenancy1.created', $start_date, $end_date1);
        })
       ->where(function ($exp, $q) use ($start_date2, $end_date2) {
            return $exp->between('Tenancy2.created', $start_date2, $end_date2);
        })->toArray();

这是我得到的。计数的数量是相同的。尽管日期不同

[
(int) 0 => object(App\Model\Entity\Tenancy) {

    'total_last_month' => (int) 4590,
    'count_last_month' => (int) 4590,
    'count_curr_month' => (int) 4590,
    'created' => object(Cake\I18n\FrozenTime) {

        'time' => '2016-03-01T10:57:21+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    },
    'Tenancy1' => [
        'created' => '2016-03-01 10:57:21'
    ],
    'Tenancy2' => [
        'created' => '2016-04-04 10:59:42'
    ],
    '[new]' => false,
    '[accessible]' => [
        '*' => true
    ],
    '[dirty]' => [],
    '[original]' => [],
    '[virtual]' => [],
    '[errors]' => [],
    '[invalid]' => [],
    '[repository]' => 'Tenancy'

}
]

即使我以这种方式编写了查询,但仍然存在同样的问题。

    $query = $tenancies->find();
    $query->select([ 
        'total_last_month' => $query->func()->count('Tenancy.id'),
    ])
    ->where([
        'Tenancy.active' => 1,
        'Tenancy.stage !=' => 1,
        'Tenancy.company_id' => $id,
    ]) 
    ->where(function ($exp) use ($start_date, $end_date) {
        return $exp->between('Tenancy.created', $start_date, $end_date);
    });

    $query->select([ 
        'count_last_month' => $query->func()->count('Tenancy1.id'),
    ])
    ->leftJoin(['Tenancy1' => 'tenancy'],[
        'Tenancy1.company_id' => $id,
    ])
    ->where([
        'Tenancy1.active' => 1,
        'Tenancy1.stage !=' => 1,
    ]) 
    ->where(function ($exp) use ($start_date, $end_date1) {
        return $exp->between('Tenancy1.created', $start_date, $end_date1);
    });

我可以看到打印的查询是正确的。

1 个答案:

答案 0 :(得分:0)

在查看文档中的所有示例之后,看起来您需要在使用func()帮助程序之前实例化ORM查询构建器实例。

  

http://book.cakephp.org/3.0/en/orm/query-builder.html#using-sql-functions

理论上$this->func()如果返回只是一个字符串,则应该相同。但是使用$this->func()可能导致您尝试构建的查询实例与未绑定的新实例之间断开连接?

尝试:

$tenancyDetails = $this>find();
$tenancyDetails->select([ 
            'total_last_month' => $tenancyDetails->find()->func()->count('Tenancy.id'),
            'count_last_month' => $tenancyDetails->find()->func()->count('Tenancy1.id'),
            'count_curr_month' => $tenancyDetails->find()->func()->count('Tenancy2.id'),
            'Tenancy.created',
            'Tenancy1.created',
            'Tenancy2.created',
        ])......        

修改

我在/ORM/query.php文件中检查了count函数的代码。 如果未设置任何值,则cake将在调用$this->func->count()上执行count()查询。 PHP编译器必须正在读取并因此在构建查询之前执行计数查询,这意味着在设置条件之前。这就是为什么你需要首先实例化类来停止计数查询过早地执行。