【发布时间】:2019-09-07 22:33:34
【问题描述】:
我有两张桌子。第一个具有主要产品数据,另一个具有这些产品的辅助描述,由第二个表上的 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_',
【问题讨论】:
-
由分页脚本确定的主要原因。代码'$products = $this->paginate($products);'有以下条件: $page = (!empty($this->request->query['pagina']) ? $this->request->query['pagina'] : 1); $this->paginate = ['page' => $page, 'limit' => '10' ];问题在于它将行内容“LIMIT 10 OFFSET 10”放在第一个 SELECT 而不是最后,在“ORDER BY title_”之后。我还不知道如何解决这个问题。
标签: cakephp cakephp-3.0 union pagination