【发布时间】:2020-06-25 10:08:45
【问题描述】:
我有一个普通的 MySQL 查询,如下所示:
SELECT d.*, IFNULL(
(SELECT GROUP_CONCAT(value) FROM display_substances `ds`
WHERE `ds`.`display_id` = `d`.`id`
AND ds.substance_id = 2
GROUP BY `ds`.`display_id`
), 'Not Listed'
) `substances` FROM displays `d`;
背景是我有两张桌子,displays 和display_substances。我想为给定的物质 ID(在上面的查询中由 ds.substance_id = 2 表示)呈现 displays 中每一行的表以及 display_substances 中的相应值。
并非displays 中的每一行都有对应的display_substances 值。如果是这种情况,它应该输出“未列出”字样。这实际上意味着如果display_substances 中没有相应的行,那么display.id 就没有数据,因此该特定行的数据库中的数据“未列出”。上面的查询正是这样做的。
我希望能够使用 CakePHP 的 ORM 语法编写查询。
表格的结构如下。
mysql> DESCRIBE displays;
+----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+------+-----+---------+----------------+
| id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| label | varchar(255) | NO | | NULL | |
+----------+----------------------+------+-----+---------+----------------+
mysql> DESCRIBE display_substances;
+--------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-----------------------+------+-----+---------+----------------+
| id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment |
| display_id | smallint(5) unsigned | NO | MUL | NULL | |
| substance_id | mediumint(8) unsigned | NO | MUL | NULL | |
| value | text | NO | | NULL | |
+--------------+-----------------------+------+-----+---------+----------------+
表类存在并定义了适当的关系。
// src/Model/Table/DisplaysTable.php
$this->hasMany('DisplaySubstances', [
'foreignKey' => 'display_id'
]);
// src/Model/Table/DisplaysSubstancesTable.php
$this->belongsTo('Displays', [
'foreignKey' => 'display_id',
'joinType' => 'INNER'
]);
到目前为止,我有这个:
$substance_id = 2;
$data =
$DisplaySubstances->find()
->contain(['Displays'])
->where(['DisplaySubstances.substance_id' => $substance_id)
->select(['Displays.id', 'Displays.label', 'Displays.anchor', 'DisplaySubstances.value'])
->enableHydration(false)->toArray();
这将为我提供displays 中的行,这些行在display_substances 中具有对应于物质 ID 2 的值。这实际上是我们拥有数据的所有内容,但不包括任何“未列出”的行。
我不知道如何使用 Cake 的 ORM 语法编写我的普通 SQL 查询的 IFNULL...GROUP_CONCAT 部分。
我已经阅读了How to use group_contact in cakephp query?,因此可以看到可以在->select() 条件中使用GROUP_CONCAT。但是链接的示例要简单得多,因为它没有使用IFNULL 条件和相应的操作(返回“未列出”)。
如果可能的话,请有人建议如何用 Cake 的 ORM 语法写这个?
CakePHP 版本为 3.5.18
【问题讨论】:
-
(不相关):建议:INDEX(substance_id, display_id, value)
标签: php mysql cakephp-3.5