我正在使用 CakePHP 3.5.13 重建一个普通的 PHP/MySQL 应用程序。
原始应用程序中的一个查询需要在同一个表上构建一个JOIN条件,并通过使用单独的表别名来实现。查询如下 - 并给出了我们期望的正确结果:
SELECT DISTINCT(s.id) FROM substances s
JOIN display_substances AS dsUses
ON (s.id = dsUses.substance_id AND dsUses.display_id = 128 AND (dsUses.value LIKE '%dye%') )
JOIN display_substances AS displays
ON (s.id = displays.substance_id AND displays.display_id NOT IN (1,2,3,4,6,128) AND (displays.value LIKE '%bpr%'))
需要这样做的原因是因为查询正在搜索 2 个单独的用户输入项 - 在同一个表 ( display_substances) 中但针对不同的display_substances .display_id字段。就上面的查询而言,它意味着:
- 搜索在
"%dye%"哪里display_id = 128 - 搜索不存在
"%bpr%"的地方display_id1,2,3,4,6 or 128
在 Cake 中,我在一个处理搜索功能的控制器中这样写:
$query = $Substances->find()->select(['id' => 'Substances.id'])->distinct();
// Search for "dye"
$query = $query->matching('DisplaySubstances', function ($q) use ($uses_summary) {
return $q->where([
'DisplaySubstances.value LIKE' => '%dye%', // "dye" is dynamic and comes from $uses_summary
'DisplaySubstances.display_id' => 128
]);
});
// Search for "bpr"
$query = $query->matching('DisplaySubstances', function ($q) use ($regulatory_information) {
return $q->where([
'DisplaySubstances.value LIKE' => '%bpr%', // "bpr" is dynamic and comes from $regulatory_information
'DisplaySubstances.display_id NOT IN' => [1,2,3,4,6,128]
]);
});
这会产生错误的 SQL,因为当我调试时$query->sql();它给出了不同的JOIN条件:
INNER JOIN display_substances DisplaySubstances ON
(
DisplaySubstances.value like "%dye%" AND DisplaySubstances.display_id = 128
AND DisplaySubstances.value like "%bpr%"
AND DisplaySubstances.display_id not in (1,2,3,4,6,128)
AND Substances.id = (DisplaySubstances.substance_id)
)
我不确定如何重写此查询,以便它将两个搜索输入中的JOIN每一个都视为一个条件,就像原始查询一样。
我注意到的主要事情是原始查询对同一个表(AS dsUses和AS displays)有不同的别名。我不确定这是否相关?
我正在尝试使用 ORM 而不是手动编写 SQL,因此更愿意知道如何使用它来执行此操作。