distinct()
без аргументов будет применяться ко всем выбранным столбцам, т. Е. Будет производиться что-то вроде:
DISTINCT c.a_id, c.b_id, c.some_data, b.id
с применением отличительных по всем столбцам, что эффективно не удалит всеиз ваших дубликатов, так как все кортежи, которые состоят из этих столбцов, будут разными.
Вам придется применять отличные только к определенным столбцам, так что на самом деле есть разница между вашими дубликатами, например, используйте Bs.id
:
$q->distinct('Bs.id');
Это создаст либо DISTINCT ON(Bs.id)
, либо GROUP BY Bs.id
, в зависимости от используемой СУБД. Кроме того, в зависимости от используемой СУБД и ее конфигурации, GROUP BY
вызовет ошибку, так как запрос выберет неагрегированные столбцы, которых нет в предложении GROUP BY
(см., Например, * 1018). * MySQL и режим ONLY_FULL_GROUP_BY
).
Чтобы обойти это ограничение, потребуется некоторая хитрость, один из способов, который я использовал в прошлом, - это использование явной посреднической ассоциации в соединенииВ таблице и выберите данные n:m
в отдельном запросе, запрос для ассоциации-посредника может затем безопасно применить группировку.
В вашем примере это будет As hasMany Cs
и Cs belongsTo Bs
, а затем будет содержатьтаблица соединений, где вы можете применить группировку, будет выглядеть примерно так:
$this->As
->find()
->contain([
'Cs' => [
'queryBuilder' => function (\Cake\ORM\Query $query) {
return $query
->select(['Cs.a_id', 'Cs.b_id'])
->group(['Cs.a_id', 'Cs.b_id']);
},
'Bs' => [
'strategy' => \Cake\ORM\Association\BelongsTo::STRATEGY_SELECT
]
]
]);
Результат, конечно, будет отформатирован по-разному, поэтому вам может потребоваться переформатировать его в случае необходимости.