CakePHP 3对联合查询的结果进行分页

问题描述 投票:0回答:1

我有两张桌子。第一个具有主要产品数据,另一个具有这些产品的次要描述,由第二个表上的products_id外键链接。

我已经创建了SQL,一切看起来都不错。但是当我转换为CakePHP 3的ORM时,使用相同的结果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']);

这是从CakePHP ORM生成的SQL结果:

    '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_',
cakephp cakephp-3.0 union paginate
1个回答
0
投票

使用以下代码解决了该问题:

$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版本。

© www.soinside.com 2019 - 2024. All rights reserved.