CakePHP 3 разбивает на страницы результат от запроса объединения - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть две таблицы.Первый содержит данные об основных продуктах, второй - вторичные описания этих продуктов, связанные внешним ключом products_id во второй таблице.

Я создал SQL, и все выглядит хорошо.Но когда я конвертирую в ORM CakePHP 3, с тем же результатом SQL-кода, это показывает большую проблему: каждая страница показывает вторичные описания из второй таблицы данных.

На первой странице индекса индекса, который имеетосновной продукт в, работает, как ожидалось.Сначала показываются основные продукты, а после этого описания показываются вторичные описания, которые находятся внутри данных вторичной таблицы.Но когда я нажимаю, чтобы увидеть следующие страницы, эти вторичные продукты есть, когда я ожидал чего-нибудь от этих данных таблицы.

Мне нужно показывать эти вторичные описания только тогда, когда основные продукты находятся на этой странице и когдане там, он не показывает записи из этой таблицы.Как и в результате SQL-сценария.

В этом сценарии SQL вы видите то, что мне нужно:

    (SELECT 
        Products.id, 
        (null) AS product_titles_id,
        (Products.title) AS title_,
        Products.product_groups_id, 
        Products.product_types_id, 
        Products.code, 
        Products.title, 
        Products.ean, 
        Products.ncm, 
        Products.obs, 
        Products.minimum, 
        Products.maximum,
        ProductTypes.id,
        ProductTypes.code,
        ProductTypes.title,
        ProductTypes.calc_cost,
        ProductGroups.id,
        ProductGroups.code,
        ProductGroups.title
    FROM `products` Products
       LEFT JOIN `product_groups` ProductGroups ON Products.product_groups_id = ProductGroups.id
       LEFT JOIN `product_types` ProductTypes ON Products.product_types_id = ProductTypes.id)

    UNION

    (SELECT 
        Products.id,
        ProductTitles.id AS product_titles_id, 
        (ProductTitles.title) AS title_,
        Products.product_groups_id, 
        Products.product_types_id, 
        -- ProductTitles.products_id, 
        ProductTitles.code, 
        ProductTitles.title, 
        Products.ean, 
        Products.ncm, 
        ProductTitles.obs,
        Products.minimum, 
        Products.maximum,
        ProductTypes.id,
        ProductTypes.code,
        ProductTypes.title,
        ProductTypes.calc_cost,
        ProductGroups.id,
        ProductGroups.code,
        ProductGroups.title
    FROM `product_titles` ProductTitles
       LEFT JOIN `products` Products ON products.id = ProductTitles.products_id
       LEFT JOIN `product_groups` ProductGroups ON Products.product_groups_id = ProductGroups.id
       LEFT JOIN `product_types` ProductTypes ON Products.product_types_id = ProductTypes.id)
    ORDER BY title_

Это результат этого сценария SQL:

    id  product_titles_id   title_
    0080    NULL              SUPORTE DE PRESSAO
    7545    NULL              BA RET.
    3177    NULL              CORT RDX
    3177    17                EMEN RDX (secondary description)
    3177    18                PART RDX (secondary description)
    6623    NULL              LATAO CALCO CALIB.
    8079    NULL              TRANSM DE PRESSAO
    4242    NULL              GY 6/6 P.U CORAL

Этоэто то, что я сделал в сценарии CakePHP ORM:

    //Main table of products
    $qry_products = $this->Products->findByParametersId('85')
            ->select(['Products.id', 'product_titles_id' => 'null', 
                      'title_' => 'Products.title', 
                      'Products.product_groups_id', 
                      'Products.product_types_id', 
                      'Products.code', 'Products.title', 
                      'Products.ean', 'Products.ncm', 
                      'Products.obs', 'Products.minimum', 
                      'Products.maximum', 'ProductTypes.id', 
                      'ProductTypes.code', 'ProductTypes.title', 
                      'ProductTypes.calc_cost', 'ProductGroups.id', 
                      'ProductGroups.code', 'ProductGroups.title', 
                      'ProductTitles' => '0'
                     ])
            ->where($where)
            ->join([
              'ProductGroups' => ['table' => 'product_groups',
                                  'type'       => 'LEFT',
                                  'conditions' => 'Products.product_groups_id = ProductGroups.id'
                                 ],
              'ProductTypes'  => ['table'      => 'product_types',
                                  'type'       => 'LEFT',
                                  'conditions' => 'Products.product_types_id = ProductTypes.id'
                                 ]
                   ])
             ->limit(20);

    //Secondary table of products' descriptions:
    $qry_productTitles = $this->ProductTitles->findByParametersId('85')
             ->select(['Products.id', 
                       'product_titles_id' =>                  'ProductTitles.id', 
                       'title_' => 'ProductTitles.title', 
                       'product_groups_id' => 'Products.product_groups_id', 
                       'product_types_id' => 'Products.product_types_id', 
                       'ProductTitles.code', 'ProductTitles.title',
                       'ean' => 'Products.ean', 
                       'ncm' => 'Products.ncm', 
                       'obs' => 'Products.obs', 
                       'minimum' => 'Products.minimum', 
                       'maximum' => 'Products.maximum',
                       'ProductTypes.id', 'ProductTypes.code', 
                       'ProductTypes.title',                            
                       'ProductTypes.calc_cost', 
                       'ProductGroups.id', 'ProductGroups.code', 
                       'ProductGroups.title', 
                       'ProductTitles' => '1'
                      ])
             ->join([
      'Products' => ['table'      => 'products',
                     'type'       => 'LEFT',
                     'conditions' => 'ProductTitles.products_id = Products.id'
                    ],
      'ProductGroups' => ['table'      => 'product_groups',
                          'type'       => 'LEFT',
                          'conditions' => 'Products.product_groups_id = ProductGroups.id'
                         ],
      'ProductTypes' => ['table'      => 'product_types',
                         'type'       => 'LEFT',
                         'conditions' => 'Products.product_types_id = ProductTypes.id'
                        ]
    ]);

    //Union these two tables and put some where conditions and ordanation:
    $products = $qry_products->union($qry_productTitles)
                             ->where($where)
                             ->epilog('ORDER BY title_');
                             //->order(['title_ ASC']);

Это результат SQL, сгенерированный из CakePHP ORM:

    'sql' => '
    (SELECT Products.id AS `Products__id`, 
     null AS `product_titles_id`, Products.title AS `title_`, 
     Products.product_groups_id AS `Products__product_groups_id`, 
     Products.product_types_id AS `Products__product_types_id`, 
     Products.code AS `Products__code`, 
     Products.title AS `Products__title`, 
     Products.ean AS `Products__ean`, 
     Products.ncm AS `Products__ncm`, 
     Products.obs AS `Products__obs`, 
     Products.minimum AS `Products__minimum`, 
     Products.maximum AS `Products__maximum`, 
     ProductTypes.id AS `ProductTypes__id`, 
     ProductTypes.code AS `ProductTypes__code`, 
     ProductTypes.title AS `ProductTypes__title`,        
     ProductTypes.calc_cost AS `ProductTypes__calc_cost`, 
     ProductGroups.id AS `ProductGroups__id`, 
     ProductGroups.code AS `ProductGroups__code`, 
     ProductGroups.title AS `ProductGroups__title`, 
     0 AS `ProductTitles` 
    FROM products Products 
    LEFT JOIN product_groups ProductGroups ON Products.product_groups_id = ProductGroups.id 
    LEFT JOIN product_types ProductTypes ON Products.product_types_id = ProductTypes.id 
    ORDER BY title_ LIMIT 20)

    UNION 

    (SELECT Products.id AS `Products__id`, 
     ProductTitles.id AS `product_titles_id`, 
     ProductTitles.title AS `title_`,  
     Products.product_groups_id AS `product_groups_id`, 
     Products.product_types_id AS `product_types_id`, 
     ProductTitles.code AS `ProductTitles__code`, 
     ProductTitles.title AS `ProductTitles__title`, 
     Products.ean AS `ean`, Products.ncm AS `ncm`, 
     Products.obs AS `obs`, Products.minimum AS `minimum`, 
     Products.maximum AS `maximum`, 
     ProductTypes.id AS `ProductTypes__id`, 
     ProductTypes.code AS `ProductTypes__code`, 
     ProductTypes.title AS `ProductTypes__title`, 
     ProductTypes.calc_cost AS `ProductTypes__calc_cost`, 
     ProductGroups.id AS `ProductGroups__id`, 
     ProductGroups.code AS `ProductGroups__code`, 
     ProductGroups.title AS `ProductGroups__title`, 
     1 AS `ProductTitles` 
    FROM product_titles ProductTitles 
    LEFT JOIN products Products ON ProductTitles.products_id = Products.id 
    LEFT JOIN product_groups ProductGroups ON Products.product_groups_id = ProductGroups.id 
    LEFT JOIN product_types ProductTypes ON Products.product_types_id = ProductTypes.id) 

    ORDER BY title_',

1 Ответ

0 голосов
/ 23 апреля 2019

Проблема была решена с помощью кода ниже:

$products_union = "((SELECT 
                       Products.id AS `id`, 
                       Products.product_groups_id, 
                       Products.product_types_id, 
                       Products.code AS `code`, 
                       Products.title AS `title`, 
                       Products.ean AS `ean`, 
                       Products.ncm AS `ncm`, 
                       Products.obs AS `obs`, 
                       Products.minimum AS `minimum`, 
                       Products.maximum AS `maximum`,
                       ProductTypes.id AS `ProductTypes__id`,
                       ProductTypes.code AS `ProductTypes__code`,
                       ProductTypes.title AS `ProductTypes__title`,
                       ProductTypes.calc_cost AS `ProductTypes__calc_cost`,
                       ProductGroups.id AS `ProductGroups__id`,
                       ProductGroups.code AS `ProductGroups__code`,
                       ProductGroups.title AS `ProductGroups__title`
                     FROM `products` Products
                     LEFT JOIN `product_groups` ProductGroups 
                            ON Products.product_groups_id = ProductGroups.id
                     LEFT JOIN `product_types` ProductTypes 
                            ON Products.product_types_id = ProductTypes.id)

                     UNION ALL

                     (SELECT 
                        Products.id AS `id`, 
                        Products.product_groups_id, 
                        Products.product_types_id, 
                        ProductTitles.code AS `code`, 
                        ProductTitles.title AS `title`, 
                        Products.ean AS `ean`, 
                        Products.ncm AS `ncm`, 
                        ProductTitles.obs AS `obs`, 
                        Products.minimum AS `minimum`, 
                        Products.maximum AS `maximum`,
                        ProductTypes.id AS `ProductTypes__id`,
                        ProductTypes.code AS `ProductTypes__code`,
                        ProductTypes.title AS `ProductTypes__title`,
                        ProductTypes.calc_cost AS `ProductTypes__calc_cost`,
                        ProductGroups.id AS `ProductGroups__id`,
                        ProductGroups.code AS `ProductGroups__code`,
                        ProductGroups.title AS `ProductGroups__title`
                      FROM `product_titles` ProductTitles
                      LEFT JOIN `products` Products 
                            ON Products.id = ProductTitles.products_id
                      LEFT JOIN `product_groups` ProductGroups 
                            ON Products.product_groups_id = ProductGroups.id
                      LEFT JOIN `product_types` ProductTypes 
                            ON Products.product_types_id = ProductTypes.id
                        ))";

    $products = $this->Products->find('all')
                               ->from([$this->Products->alias() => $products_union])
                               ->contain(['ProductTypes', 'ProductGroups'])
                               ->where($where)
                               ->order(['Products.title']);

Теперь «LIMIT» и «OFFSET» находятся в нужном месте.Я до сих пор использую версию 3.4 CakePHP.

...