функции mysql в select

Обсуждение документации. Переводы Cookbook и авторские рецепты.
Ответить
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

функции mysql в select

Сообщение rak »

Такое маленькое напоминание, а то я уже хотел писать багрепорт :)
При использовании ф-й mysql в селекте с джойном, например

Код: Выделить всё

    $criteria = new CDbCriteria();
    $criteria->select = '*, SUM(IF(type = 1, 1, 0)) AS sellersCnt';
    $criteria->with = array('profile');
    $criteria->together = TRUE;
    $sellersArray = User::model()->findAll($criteria);
 
Будет выдаваться ошибка, т.к. в CJoinElement::getColumnSelect() происходит разбиение строки select по запятым.
Для нормальной работы нужно использовать select в виде массива

Код: Выделить всё

    $criteria->select = array('*', 'SUM(IF(type = 1, 1, 0)) AS sellersCnt');
 
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: функции mysql в select

Сообщение Ekstazi »

CDbExpression гляньте.
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: функции mysql в select

Сообщение rak »

да, смотрел, но в данном случае он не поможет
Аватара пользователя
kritik
Сообщения: 20
Зарегистрирован: 2010.07.30, 19:36

Re: функции mysql в select

Сообщение kritik »

А ваш пример из первого поста работает?

Я столкнулся с проблемой

Код: Выделить всё

Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) 
Несмотря на то, что у меня

Код: Выделить всё

$criteria->select = array("SUM(price) as price"); 
в результирующем запросе SELECT включает в себя все остальные поля из relations:

Код: Выделить всё

SELECT SUM(price) as price, `t`.`id` AS `t0_c0`, `customer`.`id` AS `t1_c0`... 
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: функции mysql в select

Сообщение rak »

1. Если не работает, то какой запрос и какая ошибка?
2. Используются ли релейшены?
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: функции mysql в select

Сообщение rak »

и кстати, может проблема в именовании?
что, если попробовать так:

Код: Выделить всё

$criteria->select = array("SUM(price) as sum_price"); 
 
SpiLLeR
Сообщения: 350
Зарегистрирован: 2009.09.17, 16:47
Откуда: Санкт-Петербург
Контактная информация:

Re: функции mysql в select

Сообщение SpiLLeR »

у вас ошибка в том, что MIN(),MAX(),COUNT(), etc... должны использоватся только с GROUP BY.
Предупрежден - значит вооружен.
devKP.ru
Аватара пользователя
kritik
Сообщения: 20
Зарегистрирован: 2010.07.30, 19:36

Re: функции mysql в select

Сообщение kritik »

Проблема только в том, что несмотря на то что я указываю

Код: Выделить всё

$criteria->select = array("SUM(price) as price"); 
В результирующем запросе присутствует не только SUM(price) as price, но и поля из реляций

Код: Выделить всё

 SELECT SUM(price) as price, `t`.`id` AS `t0_c0`, `customer`.`id` AS `t1_c0`...  
поэтому вываливается ошибка GROUP BY. Если бы там осталось только SUM(price) - все было бы отлично.
Вот кусок кода:

Код: Выделить всё

public function search( $export = false , $totals = false )
    {
        $criteria = new CDbCriteria;
        $criteria->compare('product.category',$this->category);
        ...
        $criteria->compare( 'industries_c2i.industry_id' , $this->industry_id );
        
        if( $this->industry_id || $this->category ){
                      $criteria->with = array('customer.industries','product');
                       $criteria->together = true;
        }
        
        if( $totals )
        {
            $criteria->select = array("SUM(price) as price");
            $result = self::model()->find( $criteria );
            return $result->price;
        }

        return new CActiveDataProvider(get_class($this), array(
            'criteria'      => $criteria,
            'sort'           => array( 'defaultOrder' => 't.id desc' ),
            'pagination' => $export ? false : null ,
        ));
    } 
Я использую одну и ту же функцию в гриде, для экспорта и для получения суммы.
В случае если $totals = true; наблюдаю описанную ситуацию.
Если $this->industry_id || $this->category не установлены все отрабатывает отлично, но если подключаются реляции получаю ошибку.
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: функции mysql в select

Сообщение rak »

Код: Выделить всё

 if( $totals )
        {
            $criteria->select = array("SUM(price) as price");
            $criteria->with = array();
            $result = self::model()->find( $criteria );
            return $result->price;
        }

 
Аватара пользователя
kritik
Сообщения: 20
Зарегистрирован: 2010.07.30, 19:36

Re: функции mysql в select

Сообщение kritik »

$criteria->with = array();
Но тогда я не получу то что мне нужно.
Суть в том, что в зависимости от фильтра грида выводятся определенные записи и тем же запросом ( только с другим SELECT ) показывается сумма по полю price

Upd
http://www.yiiframework.com/doc/guide/1 ... .arr#sec-4
Даже если использовать 'select'=>false, все равно в запросе присутствует как минимум первичный ключ из отношения
Johnatan
Сообщения: 167
Зарегистрирован: 2010.10.27, 13:06
Откуда: Reino de España

Re: функции mysql в select

Сообщение Johnatan »

$criteria->together = true; вам там не мешает? А то сдаётся мне оно-то как раз и вызывает джоин всех ненужных таблиц.
Конференция: [email protected]
Аватара пользователя
kritik
Сообщения: 20
Зарегистрирован: 2010.07.30, 19:36

Re: функции mysql в select

Сообщение kritik »

Таблицы нужны, не нужны поля от этих таблиц в SELECT. Именно этого не удается достичь.
Я исследовал CDbCriteria и выяснил, что запрос к базе в данном случае строит CActiveFinder
Вытянуть запрос из CActiveFinder у меня не получилось.
Как вариант можно переписать свой копомпонент на основе CActiveFinder, получить из CDbCriteria запрос в чистом виде и сделать с ним все что угодно.
При беглом рассмотрении CActiveFinder стало понятно, что мне прийтется долго насиловать свой мозг до просветления как это сделать, поэтому я написал костыли, продублировав запрос со всеми джоинами на чистом SQL.

ПС. Судя по всему рано или поздно прийдется писать компонент для получения запроса из CDbCriteria, т.к. аналогичных случаев будет много, а каждый раз дубливать запрос на SQL "совесть не позволит"
Ответить