Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 11 Июл 2008 21:27:31 Заголовок сообщения: find("count") в hasMany & BT связях |
|
|
Есть две таблички
Division (hasMany staff)
Staff (belongsTo Division)
они связаны всё нормально.
$staff = $this->Division->Staff->find("count", array ("conditions" => array(("MONTH (birthday) = " . $month), "DAY (birthday) = " .$day),"group" => array("Division.id")));
По-моему разумению staff должен получиться массивом, сгруппированным по Division[id] = кол-во стаффа с бёрздником в этот месяц.
Собственно вот сгенерённый запрос:
SELECT COUNT(*) AS `count` FROM `staffs` AS `Staff` LEFT JOIN `divisions` AS `Division` ON (`Staff`.`division_id` = `Division`.`id`) WHERE MONTH (birthday) = 7 AND DAY (birthday) = 11 GROUP BY `Division`.`id`
А теперь вопрос: кейк в staff кладёт одно число, тогда как должен получаться массив. Если скормить этот запрос phpMyAdmin то на выходе получаю - массив (2,1) - по кол-ву именинников.
В кейке на выходе - 2. Всё. Никаких массивов.
Где я неправ? (версия 1.2 RC2) |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 11 Июл 2008 21:35:21 Заголовок сообщения: |
|
|
Нашёл старое решение, типа:
$this->Post->bindModel(array('hasMany' => array('Comment' =>
array('fields' => array('post_id')))));
$this->set('data', $this->Post->find('all', array('order' =>
'created DESC')));
Но это же не наш метод... |
|
Вернуться к началу |
|
|
DeeperMD
цитировать
Зарегистрирован: 08 Фев 2008 15:04:11 Сообщения: 144 Откуда: $Молдова->Кишинёв->Буюканы()
|
Добавлено: 12 Июл 2008 17:21:46 Заголовок сообщения: |
|
|
Дело не в этом.. все верно у тебя только вот немного с методом модели ты ошибся..
Model->find выдает только одну запись..
Юзай Model->findAll для получения всех резултов. |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 13 Июл 2008 00:24:47 Заголовок сообщения: |
|
|
Мне было нужно именно посчитать кол-во вхождений привязанного стаффа. А не получить данные
Т.е. я хотел получить что-то вида
[Division] => id - 1, title
staff => count
а По findAll я получу дивижен и все вхождения staff-а для конкретного дивижена.
Поигравшись с conditions и bindModel я получил почти то что хотел. Но всё равно считать приходится в ПХП. Иначе не выходит. Или весь список, или (если группировать по division.id) - только по одному вхождению для каждого division-а |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 13 Июл 2008 00:31:40 Заголовок сообщения: |
|
|
Да и конструкция
this->Division->Staff->findAll("count", array("conditions" => array (MONTH (birthday) = 7))); (birthday - В поле таблички Staff)
не работает |
|
Вернуться к началу |
|
|
Trk
цитировать
Зарегистрирован: 24 Янв 2008 17:41:58 Сообщения: 5
|
Добавлено: 13 Июл 2008 05:10:29 Заголовок сообщения: |
|
|
find("count") никогда массив тебе не вернет. Загляни хотя бы в код кейка, find("count") всегда возвращает строку с числом из поля `count` твоего запроса.
Можно так сделать:
Код: |
$conds = array(
"fields" => array("Division.id", "Division.title", "COUNT(Staff.id) as count")
,"group" => array("Division.id")
,"conditions" => array("MONTH (Staff.birthday)" => 7)
);
$this->Division->Staff->find("all", $conds);
|
Вернет что-то вроде этого:
Код: |
array(3) {
[0]=>
array(2) {
["Division"]=>
array(2) {
["id"]=>
string(1) "1"
["title"]=>
string(2) "title1"
}
[0]=>
array(1) {
["count"]=>
string(1) "3"
}
}
[1]=>
array(2) {
["Division"]=>
array(2) {
["id"]=>
string(1) "2"
["title"]=>
string(18) "title2"
}
[0]=>
array(1) {
["count"]=>
string(2) "36"
}
}
[2] => ...
}
|
|
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 13 Июл 2008 09:34:03 Заголовок сообщения: |
|
|
Trk супер. Я как-то не допетрил, что можно в fields вписать COUNT
спасибо |
|
Вернуться к началу |
|
|
zeresesker
цитировать
Зарегистрирован: 07 Ноя 2008 19:35:32 Сообщения: 8
|
Добавлено: 04 Дек 2008 10:46:49 Заголовок сообщения: |
|
|
Не знаю, апятся темы или нет, но дабы не плодить дублей, отпишусь здесь.
До того, что в поля можно пихать агрегатные функции и прочие куски сиквельного кода я додумался, но вот вывод в этом случае вызывает рвотный рефлекс.
Пусть получила массив как в примере выше, прогоняем через перебор и вывод у нас выглядит так:
$group['Division'][0]['count']
Это в вашем просто случае. В моем вложенность массива доходила до 7. Причем, если группа пустая, то значения нет и это тоже надо контролировать.
Оптимизацию кейковских запросов при такой схеме я в общем не рассматривал, поскольку возвращаемый массив меня не устраивает и работать с таким я не хочу. Могу отметить только то, что, идет выборка по первичной таблице и во втором запросе в IN подставляется список идентификаторов, а не подзапрос, это избавляет от прохода по всей таблице. Но это простой случай.
Но вопрос даже в другом - насколько подобные выборки соответствуют идеологии кейка? При подобных выборках мы получаем не объект, а таблицу. А механизмы кейка предназначены именно для получения иерархии объектов.
Можно использовать произвольный запрос, вызвав метод query модели, но и в этом случае возвращаемый массив меня не устроил - поля таблицы возвращаются массивом вида: ['TableName']['FieldName'], а агрегатные функции в отдельном нумерованном подмассиве.
Собственно проблема и варианты решения штатными кейковскими методами очерчены.
В качестве нормального решения видится написание класса DataTableModel по типу DataTable из .NET. С одной стороны это впишется в схему кейка, с другой стороны мы получим нормальную табличную выборку по произвольному запросу.
Кто что думает и как подходит к решению подобных выборок из БД? |
|
Вернуться к началу |
|
|
|