Список форумов Cake-PHP.ru Cake-PHP.ru
Форум программистов CakePHP
(на сайт)
 
 Watched TopicsWatched Topics   FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

find("count") в hasMany & BT связях

 
Начать новую тему   Ответить на тему    Список форумов Cake-PHP.ru -> Общий
Предыдущая тема :: Следующая тема  
Автор Сообщение
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
спасибо Smile
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
zeresesker

цитировать



Зарегистрирован: 07 Ноя 2008 19:35:32
Сообщения: 8

СообщениеДобавлено: 04 Дек 2008 10:46:49    Заголовок сообщения: Ответить с цитатой

Не знаю, апятся темы или нет, но дабы не плодить дублей, отпишусь здесь.
До того, что в поля можно пихать агрегатные функции и прочие куски сиквельного кода я додумался, но вот вывод в этом случае вызывает рвотный рефлекс.
Пусть получила массив как в примере выше, прогоняем через перебор и вывод у нас выглядит так:
$group['Division'][0]['count']
Это в вашем просто случае. В моем вложенность массива доходила до 7. Причем, если группа пустая, то значения нет и это тоже надо контролировать.
Оптимизацию кейковских запросов при такой схеме я в общем не рассматривал, поскольку возвращаемый массив меня не устраивает и работать с таким я не хочу. Могу отметить только то, что, идет выборка по первичной таблице и во втором запросе в IN подставляется список идентификаторов, а не подзапрос, это избавляет от прохода по всей таблице. Но это простой случай.
Но вопрос даже в другом - насколько подобные выборки соответствуют идеологии кейка? При подобных выборках мы получаем не объект, а таблицу. А механизмы кейка предназначены именно для получения иерархии объектов.
Можно использовать произвольный запрос, вызвав метод query модели, но и в этом случае возвращаемый массив меня не устроил - поля таблицы возвращаются массивом вида: ['TableName']['FieldName'], а агрегатные функции в отдельном нумерованном подмассиве.
Собственно проблема и варианты решения штатными кейковскими методами очерчены.

В качестве нормального решения видится написание класса DataTableModel по типу DataTable из .NET. С одной стороны это впишется в схему кейка, с другой стороны мы получим нормальную табличную выборку по произвольному запросу.

Кто что думает и как подходит к решению подобных выборок из БД?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Имя
Сообщение

Смайлики
Very Happy Smile Sad Surprised
Shocked Confused Cool Laughing
Mad Razz Embarassed Crying or Very sad
Evil or Very Mad Twisted Evil Rolling Eyes Wink
Exclamation Question Idea Arrow
Дополнительные смайлики

 
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов Cake-PHP.ru -> Общий Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы можете начинать темы
Вы можете отвечать на сообщения
Вы можете редактировать свои сообщения
Вы можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2005 phpBB Group
Русская поддержка phpBB

Рейтинг@Mail.ru