Cakephp 3 - Проблема преобразования пользовательских подзапросов - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь преобразовать свой пользовательский подзапрос в мой синтаксис модели CakePHP 3, но у меня возникают проблемы. Ниже мой запрос, который работает нормально, если я делаю пользовательский запрос.

$connection = ConnectionManager::get('default');
$results = $connection->execute("
    SELECT
        res.*, sa.sp_qty,
        (sa.sp_qty - SUM(received + dumped +quarantined)) as remaining_qty
    FROM (
        SELECT
            SUM(rs_receive_qty) as received,
            SUM(rs_damage_qty) as dumped,
            qs.qs_qty as quarantined,
            rs_sp_id
        FROM
            `fp_received_stock` rs 
        INNER JOIN
            fp_quarantine_stock qs ON
                qs.qs_sp_id = rs.rs_sp_id 
        WHERE
            `rs_sa_id` LIKE 'cbb31e17077e8ba0f6902d8416198dd4' 
        GROUP BY
            rs_sp_id
    ) as res
    INNER JOIN
        fp_stock_product sa ON
            sa.sp_sa_id = 'cbb31e17077e8ba0f6902d8416198dd4' AND
            sa.sp_id = res.rs_sp_id
    GROUP BY
        res.rs_sp_id
    HAVING
        remaining_qty > 0
    ")
    ->fetchAll('assoc');

echo '<pre>';
print_r($results);

Если я распечатаю этот запрос, я получаю правильные данные с массивом, как показано ниже.

Array
(
    [0] => Array
        (
            [received] => 10
            [dumped] => 0
            [quarantined] => 5
            [rs_sp_id] => 9d5743062b93e0dea1f6b4220e8d599d
            [sp_qty] => 20
            [remaining_qty] => 5
        )

    [1] => Array
        (
            [received] => 5
            [dumped] => 1
            [quarantined] => 1
            [rs_sp_id] => a78606f989da4b6565aee8f6b13ab6e1
            [sp_qty] => 10
            [remaining_qty] => 3
        )

)

Сейчас я пытаюсь преобразовать этот запрос с помощью Cakephp 3, и ниже я делаю то, что сейчас делаю.

$ReceivedStock = $this->loadModel('ReceivedStock');
$stocks = $this->loadModel('Stocks');

$subquery = $ReceivedStock->find('all');
$subquery = $subquery
    ->select([
        'received' => $subquery->func()->sum('rs_receive_qty'),
        'dumped' => $subquery->func()->sum('rs_damage_qty'),
        'quarantined' =>'qs.qs_qty',
    ])
    ->innerJoin(
        ['qs' => 'fp_quarantine_stock'],
        ['qs.qs_sp_id = ReceivedStock.rs_sp_id']
    )                                        
    ->where([
        'rs_sa_id = "cbb31e17077e8ba0f6902d8416198dd4"'
    ])
    ->group('rs_sp_id');

$stocksList = $stocks->find('all');
$stocksList
    ->select([
        'ReceivedStock__res.*',
        'sa.sp_qty',
        'remaining_qty' => 'sa.sp_qty - ' . $subquery->func()->sum('received + dumped + quarantined'),
        'ReceivedStock__res' => $subquery,
    ])
    ->innerJoin(
        ['sa' => 'fp_stock_product'],
        [
            'sa.sp_sa_id' => "cbb31e17077e8ba0f6902d8416198dd4",
            'sa.sp_id' => 'res.rs_sp_id'
        ]
    )                        
    ->group('ReceivedStock__res.rs_sp_id')
    ->having([
        'remaining_qty >' => 0
    ])
    ->toArray();

print_r($stocksList);exit;

Но я получаю сообщение об ошибке

SQLSTATE [42000]: синтаксическая ошибка или нарушение доступа: 1064 В синтаксисе SQL есть ошибка; проверьте руководство, соответствующее вашей версии сервера MySQL, чтобы узнать правильный синтаксис для использования рядом с 'AS ReceivedStock__res__*, sa.sp_qty AS sa__sp_qty, sa.sp_qty - AS `остаются в' в строке 1

А вот так выглядит мой преобразованный sql-запрос.

SELECT
  Stocks.sa_id AS Stocks__sa_id,
  Stocks.sa_batch_no AS Stocks__sa_batch_no,
  Stocks.sa_storage_id AS Stocks__sa_storage_id,
  Stocks.sa_supplier_id AS Stocks__sa_supplier_id,
  Stocks.sa_company_id AS Stocks__sa_company_id,
  Stocks.sa_receiving_contact_name AS Stocks__sa_receiving_contact_name,
  Stocks.sa_delivery_date AS Stocks__sa_delivery_date,
  Stocks.sa_notes_for_sl AS Stocks__sa_notes_for_sl,
  Stocks.sa_ref_document_1 AS Stocks__sa_ref_document_1,
  Stocks.sa_ref_document_2 AS Stocks__sa_ref_document_2,
  Stocks.sa_status AS Stocks__sa_status,
  Stocks.sa_created_by AS Stocks__sa_created_by,
  Stocks.sa_modified_by AS Stocks__sa_modified_by,
  Stocks.sa_created_date AS Stocks__sa_created_date,
  Stocks.sa_modified_date AS Stocks__sa_modified_date,
  ReceivedStock__res.* AS ReceivedStock__res__ *,
  sa.sp_qty AS sa__sp_qty,
  sa.sp_qty - AS remaining_qty,
  (
  SELECT
    (SUM(rs_receive_qty)) AS received,
    (SUM(rs_damage_qty)) AS dumped,
    qs.qs_qty AS quarantined
  FROM
    fp_received_stock ReceivedStock
  INNER JOIN
    fp_quarantine_stock qs ON qs.qs_sp_id = ReceivedStock.rs_sp_id
  WHERE
    rs_sa_id = "cbb31e17077e8ba0f6902d8416198dd4"
  GROUP BY
    rs_sp_id
) AS ReceivedStock__res
FROM
  fp_stock_adjustment Stocks
INNER JOIN
  fp_stock_product sa ON(
    sa.sp_sa_id = : c0 AND sa.sp_id = : c1
  )
GROUP BY
  ReceivedStock__res.rs_sp_id
HAVING
  remaining_qty > : c2

Может кто-нибудь подсказать, что я здесь делаю не так?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

ОК, ребята, в конце концов я придумала собственное решение. Здесь ниже мой рабочий код.

 $sa_id = $requestformData['sa_id'];
            // status check 
            $ReceivedStock = $this->loadModel('ReceivedStock');
            $stocks = $this->loadModel('Stocks');

            $subquery = $ReceivedStock->find('all');
            $subquery = $subquery->select([
                'received' => $subquery->func()->sum('rs_receive_qty'),
                'dumped' => $subquery->func()->sum('rs_damage_qty'),
                'quarantined' => 'if (qs.qs_qty IS NULL,0,qs.qs_qty)',
                'rs_sp_id' => 'rs_sp_id'
            ])
                ->leftJoin(['qs' => 'fp_quarantine_stock'], ['qs.qs_sp_id = ReceivedStock.rs_sp_id'])
                ->where([
                    'rs_sa_id = "' . $sa_id . '"',

                ])
                ->group('rs_sp_id'); //->toArray();

            $checkStockAdjustStatus = $this->ReceivedStock
                ->find()
                ->select([
                    'sub.received',
                    'sub.dumped',
                    'sub.quarantined',
                    'sub.rs_sp_id',
                    'sa.sp_qty',
                    'remaining_qty' => "sa.sp_qty - SUM(sub.received+sub.dumped+sub.quarantined)"

                ])
                ->innerJoin(['sa' => 'fp_stock_product'], [
                    'sa.sp_sa_id = "' . $sa_id . '"',
                    'sa.sp_id = rs_sp_id'
                ])
                ->from(['sub' => $subquery])
                ->group('rs_sp_id')
                ->having(['remaining_qty >' => 0])
                ->toArray();

Надеюсь, это поможет тому, кто застрял в подобной ситуации.

0 голосов
/ 08 января 2019

Я думаю, вам нужно изменить способ использования счетчика

 $stocksList->select([
        'ReceivedStock__res.*',

К

->select(['ReceivedStock__res' => $subquery->func()->count('*'),])

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

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