2017-05-01 7 views
2

サブクエリの仕組みを理解するのに苦労しています。条件の2つのフィールド/列を比較するには?

私が持っている想像:

$schools 
     ->select($this->Schools) 
     ->select([ 
      'pupilcount' => $this->Pupils 
       ->find() 
       ->select([ 
        $this->Pupils->find()->func()->count('*') 
       ]) 
       ->where([ 
        'Pupils.school_id' => 'Schools.id', 

       ]), 

私が経験しています問題は(私が思うに)Schools.idは常に0であるので、カウントが0として返され、私は生徒が参加引き出すことができるということです、それは生徒を示しそこ。

私は追加するには、私のコードを変更してみました:

->select(['SCID' => 'Schools.id']) 

と参照サブクエリではなく、動作しません、それは常にpupilcountために0を返すこと。

私はここで間違っていますか?

+0

チェックも参照してください。生成されたSQL式オブジェクトでない限り、条件の右辺は常にパラメータとしてバインドされます。つまり、文字列リテラルと比較しています。 – ndm

+0

私はそれを表現する必要がありますか?はい、私はSQLの – Sammaye

+0

@ndmで私は、Expressionオブジェクトの関数を見たが、私はまだどちらが選択するかわかりません、私はちょうど "これを識別器として扱わない"と表示されないことがわかります – Sammaye

答えて

5

クエリの問題が発生するたびに、実際にどのクエリが生成されているかを確認します(たとえば、DebugKitを使用)。 、列名は識別子である必要があり、互換性を引用一般的に適切な自動車用

Pupils.school_id = 'Schools.id' 

:表現オブジェクトをされていない限り、条件の右側には、常にあなたが文字列リテラルに対して比較している。すなわち、パラメータとしてバインドされます表現。左手側は自動的に正しく処理されますが、右手側は手動で扱う必要があります。

->where(function (\Cake\Database\Expression\QueryExpression $exp) { 
    return $exp->equalFields('Pupils.school_id', 'Schools.id'); 
}) 

単にインスタンス化することによって、手動で識別子式を作成することも可能です:あなたは簡単にフィールド/列を比較し、あなたがやろうとしている正確に何のためのメンターである、QueryExpression::equalFields()を利用することができる、あなたの特定のケースで

それら:

->where([ 
    'Pupils.school_id' => new \Cake\Database\Expression\IdentifierExpression('Schools.id') 
]) 

そして最後に、あなたはまた、常にしかし、その場合には、識別子が引用識別子自動の対象になりません、基本的には生のSQLクエリなどに挿入された単一の文字列値を、渡すことができます。

->where([ 
    'Pupils.school_id = Schools.id' 
]) 

+0

Aha完璧、私は感謝を覚えておく必要があります。私はまだまだケーキのちょっとした午前で、私は一緒に勉強することを学ぶ – Sammaye

+0

私は料理本を見ていますが、私は 'equalFields'を見つけることができません。 – Sammaye

+2

@Sammaye料理本は、完全なAPIではなく、一般的な概念と最も関連性の高いトピックをカバーしています。条件の追加方法の一般的な概念を知っている場合は、QueryExpression APIを検査するときにこれを見つけ出すことになります(Cookbookの例でIDEの完成/検査をサポートするために適切な型ヒントが使用されても問題ありません) 。私が個人的にどのように見つけたら、私はいつもAPIのドキュメントとソースコードを勉強しています.CakePHPの場合は私も時々貢献していますので、ここまで集中的に勉強しました。 – ndm

関連する問題