3

groupcontainfieldsおよびordera のオプションは認識していfind()ますが、CakePHP 2.2.3 で次のクエリを作成できないようです。

SELECT `User`.*, SUM(`Influence`.`id`) AS matches
FROM `db`.`users` AS `User` 
    LEFT JOIN `db`.`influences_users` AS `InfluencesUser` ON (`User`.`id` = `InfluencesUser`.`user_id`) 
    LEFT JOIN `db`.`influences` AS `Influence` ON (`InfluencesUser`.`influence_id` = `Influence`.`id`)
WHERE 1 = 1
AND `Influence`.`id` IN (1, 2, 3, 4)
GROUP BY `User`.`id` 
ORDER BY COUNT(`Influence`.`id`) DESC

基本的に、テーブルの関数を使用して、1、2、3、および 4の配列Usersを取得してから、 で並べ替えようとしています。InfluencesCOUNT()InfluencesCOUNT() DESC

Model::query()CakePHPでそうするためのきれいな方法はありますか(ハックや関数のようなものは使いたくないです)。


編集: 私は自分の問題に何も変更していませんがそれは実際にはではありませんでした。SUM()COUNT()

4

3 に答える 3

5

を使用して、次のクエリに対してのみ仮想フィールドを動的に追加できます

$this->virtualFields['matches'] = 'SUM(Influence.id)';

次に、それを結果配列に直接入れて操作します。

echo $user['User']['matches']; // if you query on the User model that is

また、注文/条件などで使用することもできます:

'order' => array('User__matches' => 'DESC')

ただし、他のすべてのモデルを「belongsTo」として持つモデルで作業する必要があります! したがって、「InfluencesUser」で作業し、「Influence」と「User」を含めます

だからあなたの場合:

$this->User->InfluencesUser->virtualFields['matches'] = 'SUM(Influence.id)';
...
$results = $this->User->InfluencesUser->find(...)

echo $result['InfluencesUser']['matches']; //in the view

'order' => array('InfluencesUser__matches' => 'DESC')
于 2012-11-26T13:24:26.650 に答える
2

ハックしすぎず、誰かがより良い解決策を持っていない限り(私が得た回答の数を見ると、それほど多くはありません)、解決策を見つけることができました。

$this->User->virtualFields['matches'] = 'COUNT(InfluencesUser.influence_id)';
$matches = $this->User->find(
        'all',
        array(
            'joins' => array(
                array(
                    'alias' => 'InfluencesUser',
                    'table' => 'influences_users',
                    'type' => 'LEFT',
                    'conditions' => array(
                        'InfluencesUser.influence_id' => $userInfluences, //$userInfluences contains the list of influences I want to do the restriction on
                        '`InfluencesUser`.`user_id` = `User`.`id`'
                    )
                )
            ),
            'group' => 'User.id',
            'order' => array('User__matches' => 'DESC'),
        ));


大きなテーブルを作成するために 、手動でInfluencesUserテーブルに参加します (実際にはテーブルは必要ありません。Influenceのリストのみが必要です)。マークの答えのおかげで、テーブルでinfluence_id制限(influence_id)を実行する必要がありました。その後、フィールドを結果配列に追加できます。joingoup bycount()count()

明らかに、パラメーターのようなものを使用したかったのですが、この特定の状況で でcontain達成できることを実行できないようです。join

これにより、一部の人々の時間を節約できることを願っています。

于 2012-11-27T10:36:34.050 に答える
0

サブクエリはどうですか?

http://book.cakephp.org/2.0/en/models/retriving-your-data.html#sub-queries

HATBM の問題に対してこのアプローチを使用して質問に回答しました。これは、複雑なクエリに役立つアプローチです。

于 2012-11-26T16:59:37.513 に答える