Запрос Cakephp для получения данных последнего отдельного поля от нескольких пользователей

У меня есть таблица с именем Transaction с отношением User, в транзакции есть поле с именем balance.

Данные выглядят так:

id  user_id  balance 
1   22       365
2   22       15
3   22       900
4   32       100
4   32       50 

Мне нужны ассоциативные данные всех пользователей и последнее поле баланса вставки User. Например, здесь id=3 — это последние вставленные данные для user_id=22.

В необработанном SQL я пробовал это:

select * from transactions where id in (select max(id) from transactions group by user_id)

Если я добавлю сюда внутреннее соединение, я знаю, что также могу получить данные пользователя. Но как я могу сделать это в CakePHP?


person Satu Sultana    schedule 12.01.2016    source источник
comment
Просто напишите эффективное выражение SQL и используйте запрос Cakephp. метод. Не существует простого / визуально приятного / простого в обслуживании способа реализации через find. ИМО: лучше использовать query и писать хорошие комментарии.   -  person AgRizzo    schedule 12.01.2016
comment
Я знаю о методе запроса, но хочу применить его в формате cakephp.   -  person Satu Sultana    schedule 12.01.2016


Ответы (1)


ИМХО, подзапросы уродливы в CakePHP 2.x. Вы также можете жестко закодировать оператор SQL и выполнить его через query(), как это было предложено @AgRizzo в комментариях.

Однако, когда дело доходит до извлечения последнего (самого большого, самого старого и т. д.) элемента в группе, есть более элегантное решение.

В этом скрипте SQL я применил метод, описанный в

Эквивалент CakePHP 2.x будет таким:

$this->Transaction->contains('User');

$options['fields'] = array("User.id", "User.name", "Transaction.balance");

$options['joins'] = array(
    array('table' => 'transactions',
        'alias' => 'Transaction2',
        'type' => 'LEFT',
        'conditions' => array(
            'Transaction2.user_id = Transaction2.user_id',
            'Transaction.id < Transaction2.id'
        )
    ),
);

$options['conditions'] = array("Transaction2.id IS NULL");

$transactions=$this->Transaction->find('all', $options);
person Inigo Flores    schedule 12.01.2016
comment
Вам нужно сравнить столбец идентификатора, а не столбец баланса. - person AgRizzo; 13.01.2016
comment
@AgRizzo Ты прав, не знаю, почему я запутался. Отредактировал ответ. Спасибо! - person Inigo Flores; 13.01.2016
comment
Безопасно ли использовать query()? - person Satu Sultana; 13.01.2016
comment
Это безопасно, пока вы не открываете его для возможных уязвимостей SQL-инъекций. См. этот вопрос. - person Inigo Flores; 13.01.2016