Cakephp 在 postgres 中获取关联求和组

问题描述

我有两张桌子

coins       summary_coins 
--------    -------------
id | name    id| date                |  get_count | coin_id
===|====    ==============================================
 1 |lira     1 | 2020-02-16 16:55:50 |  20        | 1
 2 |A        1 | 2020-03-16 16:55:50 |  12        | 1
 3 |B        1 | 2020-03-16 16:55:50 |  20        | 1

我的预期结果

name get_count   prevIoUs_month_count  
Lira 32          20

我尝试了下面的 cakePHP 方法来获得预期的结果

    public function getCount($start_date,$end_date,$prevIoUs_month_start_date,$prevIoUs_month_end_date)
    {
        $query = $this->find();
        $query
            ->select([
                        'Coins.id','Coins.name','curr_get_count' => $query->func()->sum('SummaryCoins.get_count'),'prev_get_count' => $query->func()->sum('SummaryCoins.get_count'),])
            ->matching('SummaryCoins')
            ->where([
                'SummaryCoins.user_id' => 1,'SummaryCoins.date >' => '2021-04-01','SummaryCoins.date <' => '2021-05-31'
            ])
            ->group([
                'Coins.id',]);
        return $query;
   }

这里我得到了当前月份范围,我将如何获得上个月的计数?

解决方法

有很多方法可以实现这一点,子查询、多个自定义连接、case 表达式等...

我建议您先尝试 case 表达式,根据您的日期条件,您可以返回 SummaryCoins.get_countNULLSUM 会忽略)或 {{1} } (如果您希望总和为 0 而不是 0 如果没有行符合您的条件),例如生成 SQL 如下:

NULL
SUM(
    CASE WHEN
        SummaryCoins.date >= '2020-03-01' AND
        SummaryCoins.date <= '2020-03-31'
    THEN
        SummaryCoins.get_count
    ELSE
        0
    END
)

还要注意,你应该使用$query ->select([ 'Coins.id','Coins.name','curr_get_count' => $query->func()->sum( $query ->newExpr() ->addCase( [ $query->newExpr()->add([ 'SummaryCoins.date >=' => $start_date,'SummaryCoins.date <=' => $end_date,]) ],[$query->identifier('SummaryCoins.get_count'),0] [null,'integer'] ) ),'prev_get_count' => $query->func()->sum( $query ->newExpr() ->addCase( [ $query->newExpr()->add([ 'SummaryCoins.date >=' => $previous_month_start_date,'SummaryCoins.date <=' => $previous_month_end_date,]),],]) >=来使条件包含在内,否则如果时间部分是{{1},则月份的第一天和最后一天将被忽略}.

另见

,

我也是用另一种方式写的

    public function queryBasic()
    {
            $query = $this->find();
            $query
                ->select([
                    'Coins.id','Coins.file_type','Coins.image_upload_datetime','Coins.is_image_uploaded','curr_get_count' => "SUM(SummaryCoins.get_count) filter (where SummaryCoins.date >= '2021-04-01' and SummaryCoins.date < '2021-04-30')",'prev_get_count' => "SUM(SummaryCoins.get_count) filter (where SummaryCoins.date >= '2021-05-01' and SummaryCoins.date < '2021-05-31')",])
                ->matching('SummaryCoins')
                ->where([
                    'SummaryCoins.user_id' => 1,'SummaryCoins.date >' => '2021-04-01','SummaryCoins.date <' => '2021-05-31'
                ])
                ->group([
                    'Coins.id',])
            ;
            return $query;
   }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...