用于查询的CakePHP 3.x逻辑

时间:2015-10-23 02:57:54

标签: cakephp cakephp-3.0

当我使用查询时,我可以创建如下的逻辑:

     $dateCreated = $query->func()->date_format([
        'created' => 'literal',
        "'%Y-%m-%d'" => 'literal'
    ]);

    $tableData = $eventTicketSalesTable->find()
        ->select([
            'invoiceNumber'     => 'invoice_number', 
            'dateCreated'       => $dateCreated, 
            'status'            => $status,
            'eventCode'         => 'e.code', 
            'paymentMode'       => 'p.name',
        ])
        ->join([
            'p' => [
                'table' => 'payments',
                'type' => 'INNER',
                'conditions' => 'EventTicketSales.payment_id = p.id',
            ],

请注意$dateCreated是一个单独的匿名函数,仅从created内的日期时间字段EventTicketSalesTable中提取日期。

我想知道是否有类似的方法来填充$status

$status取决于联接中的字段以及实际的EventTicketSalesTable

E.g。

如果PaymentsTableamount_collected小于EventTicketSalesTableamount_billed,那么我希望$status是一个字符串,表示'未付费'

如果EventTicketSalesTablecancelled是布尔值true,那么我希望$status是一个字符串,表示'已取消'。

等等。

如果无法创建这样的单独匿名函数,那么获得相同结果的更好方法是什么?

另一种方式,我可以想到的是在呈现之前循环结果。如果可能,我想避免这种情况。

结果以json API调用的形式发送。

1 个答案:

答案 0 :(得分:1)

在SQL级别,您正在查找CASE语句。

use Cake\Database\Expression\IdentifierExpression;

// ...

'status' => $query->newExpr()->addCase([
    $query->newExpr()->lt(
        'PaymentsTable.amount_collected',
        new IdentifierExpression('EventTicketSalesTable.amount_billed')
    ),
    $query->newExpr()->eq('EventTicketSalesTable.cancelled', true, 'boolean')
], [
    'Not Paid',
    'Cancelled',
    'Default'
])

这会产生类似

的选择
(
    CASE
        WHEN
            PaymentsTable.amount_collected < EventTicketSalesTable.amount_billed
            THEN 'Not Paid'
        WHEN
            EventTicketSalesTable.cancelled = 1
            THEN 'Cancelled'
        ELSE
            'Default'
    END
) AS `status` 

<强> Cookbook > Database Access & ORM > Query Builder > Case Statements

与所有每行功能一样,这会带来性能下降。因此,根据您处理的数据量,事后将其格式化为result formatter可能会成为更好的方法。