我有以下两个联想:
日程日期hasOne
图像说明
日程日期hasMany
照片
当我执行此查询时:
$dates = $this->AgendaDates
->find()
->order(['AgendaDates.date' => 'ASC'])
->contain(['ImageDescriptive' => function ($q) { // AgendaDates hasOne ImageDescriptive
return $q->find('translations');
}])
->limit(2);
我有以下错误:
SQLSTATE[42000]:语法错误或访问冲突:1055 ORDER BY子句的表达式#1不在GROUP BY子句中,并且包含非聚集列'brigittepatient.AgendaDates.date',该列在功能上与GROUP BY子句中的列无关;这与sql_mode=only_full_group_by不兼容
返回错误的SQL查询是:
SELECT
FichiersI18n.id AS FichiersI18n__id,
FichiersI18n.locale AS FichiersI18n__locale,
FichiersI18n.model AS FichiersI18n__model,
FichiersI18n.foreign_key AS FichiersI18n__foreign_key,
FichiersI18n.field AS FichiersI18n__field,
FichiersI18n.content AS FichiersI18n__content
FROM
fichiers_i18n FichiersI18n
INNER JOIN (
SELECT
(ImageDescriptive.id)
FROM
agenda_dates AgendaDates
LEFT JOIN fichiers ImageDescriptive ON (
ImageDescriptive.model = 'AgendaDates'
AND ImageDescriptive.field = 'image_descriptive'
AND AgendaDates.id = ImageDescriptive.foreign_key
)
GROUP BY
ImageDescriptive.id
ORDER BY
AgendaDates.date ASC
LIMIT
2
) ImageDescriptive ON FichiersI18n.foreign_key = ImageDescriptive.id
WHERE
FichiersI18n.model = 'Fichiers'
奇怪的是,当我做同样的事情,但与照片(链接到议程日期的hasMany
,而不是hasOne
):
$dates = $this->AgendaDates
->find()
->order(['AgendaDates.date' => 'ASC'])
->contain(['Photos' => function ($q) { // AgendaDates hasMany Photos
return $q->find('translations');
}])
->limit(2);
我没有错误,查询如下所示:
SELECT
FichiersI18n.id AS FichiersI18n__id,
FichiersI18n.locale AS FichiersI18n__locale,
FichiersI18n.model AS FichiersI18n__model,
FichiersI18n.foreign_key AS FichiersI18n__foreign_key,
FichiersI18n.field AS FichiersI18n__field,
FichiersI18n.content AS FichiersI18n__content
FROM
fichiers_i18n FichiersI18n
INNER JOIN (
SELECT
(Photos.id)
FROM
fichiers Photos
WHERE
(
Photos.model = 'AgendaDates'
AND Photos.field = 'photos'
AND Photos.foreign_key in (5, 3)
)
GROUP BY
Photos.id
) Photos ON FichiersI18n.foreign_key = Photos.id
WHERE
FichiersI18n.model = 'Fichiers'
我真的不明白为什么我的cakephp查询在hasOne
关联的情况下会抛出错误,而在hasMany
关联的情况下却不会?
1条答案
按热度按时间dw1jzc5e1#
严格分组
only_full_group_by
模式要求SELECT
、HAVING
和ORDER BY
中的所有字段必须是功能相关的(列a
唯一确定列b
)或聚合。分组时,组中列的所有值不一定都相等,假设有一个
Articles hasMany Comments
关系,如果加入Comments
并按Articles.id
分组,则Articles
的所有列都可以由id
主键列确定,但Comments
的列不能确定,每个Article.id
可以有多个不同的Comments
列值,如下所示:| Articles.id | Comments.created |
| - -|- -|
| 一个|2022年1月1日|
| 一个|2022年1月2日|
| 2个|2022年2月1日|
| 2个|2022年2月2日|
如果有这样的结果,那么当要求MySQL按
Comments.created
值排序时,MySQL将不知道从组中选择两个不同的Comments.created
值中的哪一个,因此发出一个可能产生这样的结果的查询将抛出错误。当严格分组方式被禁用时,MySQL将被允许从组中随机选取一个值,这使得结果不可预测,这可能是一个问题。使用聚合可以解决这个问题,例如
MIN(Comments.created)
使用组中的最小日期值。你可以在文档中找到更多关于这个主题的信息,通常在互联网上都可以找到:
有多个与有一个
您的两个查询产生不同的SQL,
hasMany
关联总是在单独的查询中检索,这是您调用translations
查找器的地方,一个单独的查询,其中没有发生连接、排序和限制,因此翻译的分组不会导致任何问题,因为只涉及用于分组的一个字段。默认情况下,
hasOne
关联使用连接,因此是一个查询,因此在这里,您要对该查询调用translations
查找器,在该查询中,您要进行排序和限制,这就是翻译分组和引用组中字段的排序之间冲突的根源。tl;dr
通过对翻译行为使用
select
策略应该可以避免此问题,该策略将使用查询得主键而不是应用了分组得子查询来获取翻译:对
ImageDescriptive
关联使用INNER
连接可能也会解决这个问题(即,如果查询可能产生的多个null
值是函数依赖问题的根源),但当涉及null
值时,它当然会改变查询记录的方式。