Как написать такой оператор COALESCE()
в построителе запросов?CakePHP 3 - Как написать COALESCE (...) в построителе запросов?
SQL
SELECT COALESCE(n.value, p.value) AS value
FROM nodes n
LEFT JOIN parents p ON p.id = n.parent_id
PHP
я могу получить как ребенка и родительские ценности, а затем пройти через результирующий набор и использовать только родитель один, если ребенок один пуст, но если есть более элегантный способ создать его в самом запросе, я бы предпочел это.
$child = $this->Nodes->find()
->select(['id', 'value'])
->where(['Nodes.id' => $id])
->contain([
'Parents' => function ($q) {
return $q->select('value');
}
])
->first();
if (empty($child->value)) {
$child->value = $child->parent->value;
}
Update 1
Так это то, что у меня есть на данный момент, но он не работает.
$child = $this->Nodes->find()
->select(['id', 'value'])
->where(['Nodes.id' => $id])
->contain([
'Parents' => function ($q) {
return $q->select([
'value' => $q->func()->coalesce([
'Nodes.value',
'Parents.value'
])
]);
}
])
->first();
Возвращает:
object(Cake\ORM\Entity) {
'id' => (int) 234,
'value' => (float) 0,
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Nodes'
}
Значение ребенка NULL
и родитель значение 1.00
так что я бы ожидать, что значение объекта будет 'value' => (float) 1.00
, но я предполагаю, что он выходит из запроса, как FALSE
преобразуется в (float) 0
.
Update 2
кажется альясинга в сливаться, имя, которое уже существует как нормальное поле не работает. Это требует уникального имени поля для результата объединения.
Update 3
Я сделал еще один тест и выбрал name
поле из двух таблиц вместо этого, и он просто возвращает фактические строки я введенные в функцию (они не получают оценены как имена столбцов):
return $q->select([
'value' => $q->func()->coalesce([
'Nodes.name',
'Parents.name'
])
]);
Возвращаемый объект имеет:
'value' => 'Nodes.name'
Так что мой новый Questio n было бы, как заставить построитель запросов оценивать строки как имена таблиц и полей?
Заметим, что 'COALESCE (n.value, p.value) AS value' является предпочтительным способом написания этого – rjdown
COALESCE также поддерживается ОРМ (не то, что он помогает ваш вопрос вообще!): HTTP : //api.cakephp.org/3.3/class-Cake.Database.FunctionsBuilder.html#_coalesce – burzum
@rjdown Спасибо, я обновил вопрос. – BadHorsie