2015-10-23 2 views
0

я могу создать логику таких как следующий, когда я использую запрос:CakePHP 3.x логики для запроса

 $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.

если PaymentsTable. amount_collected меньше, чем EventTicketSalesTable. amount_billed, тогда я хочу, чтобы строка $status была написана «Не оплачена».

если EventTicketSalesTable. cancelled имеет значение boolean true, тогда я хочу, чтобы строка $status была строкой с надписью «Отменено».

и так далее.

Если создать отдельную анонимную функцию, подобную этой, невозможно, что было бы лучшим способом добиться того же результата?

Другой способ, я могу думать о том, чтобы пройти через результаты, прежде чем представлять его. Я хочу избежать этого, если это возможно.

Результат отправляется как вызов json API.

ответ

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 может оказаться лучшим подходом.

Смежные вопросы