2017-06-23 28 views
0

CakePHPのコントローラで、2つの日付の違いを調べようとしています。ここで私が知っている通常のクエリは、従来のSQLで動作します。CakePHP TIMESTAMPDIFF in SELECT文

SELECT TIMESTAMPDIFF(SECOND, posts.post_date, answers.answer_date) AS 'timestampdiff' 
FROM answers 
INNER JOIN questions ON answers.question_id = questions.id 
INNER JOIN tags_questions ON questions.id = tags_questions.question_id 
INNER JOIN tags ON tags.id = tags_questions.tag_id 
INNER JOIN posts ON posts.id = questions.posts_id WHERE tags.id = 1; 

これはCakePHP3.0(これは私が使っているバージョンです)です。私は同じ正確なクエリ(上に示した)を構築しようとしていますが、クエリビルダCakePHPを使用しています。私は以下のクエリを構築しました。

$time_diffs = $this->Answers->find('all') 
->join(['Questions' => [ 
    'table' => 'questions', 
    'type' => 'INNER', 
    'conditions' => array('Answers.question_id = Questions.id') 
]]) 
->join(['TagsQuestions' => [ 
    'table' => 'tags_questions', 
    'type' => 'INNER', 
    'conditions' => array('TagsQuestions.question_id = Questions.id') 
]]) 
->join(['Tags' => [ 
    'table' => 'tags', 
    'type' => 'INNER', 
    'conditions' => array('TagsQuestions.tag_id = Tags.id') 
]]) 
->join(['Posts' => [ 
    'table' => 'posts', 
    'type' => 'INNER', 
    'conditions' => array('Questions.post_id = Posts.id') 
]]) 
->select(['timestampdiff' => 'TIMESTAMPDIFF(SECOND, Posts.post_date, Answers.answer_date)']) 
->where(['Tags.id' => 1])->toArray(); 

ここでエラーが発生します。

"エラー:SQLSTATE [42000]:構文エラーまたはアクセス違反:1064、SQL構文にエラーがあります。あなたのMariaDBに対応するマニュアルをチェックしてください。正しい構文が「SECOND、Posts.post_date、Answers.answer_date」の近くで使用するためのサーバーバージョン)AS 'timestampdiff' FROM '1'

CakePHPがどのような種類のクエリを生成したかを調べると、最初に書いたもの(最初のコードブロック)と似たような、わずかに異なるクエリが見つかりました。今ここに

SELECT TIMESTAMPDIFF(`SECOND, posts.post_date, answers.answer_date`) AS 'timestampdiff' 
FROM answers 
INNER JOIN questions ON answers.question_id = questions.id 
INNER JOIN tags_questions ON questions.id = tags_questions.question_id 
INNER JOIN tags ON tags.id = tags_questions.tag_id 
INNER JOIN posts ON posts.id = questions.posts_id WHERE tags.id = 1; 

が、私は理解していない部分であり、なぜCakePHPは奇数それらを生成しなかった `CakePHPではTIMESTAMPDIFFのための私のパラメータの周りの記号を引用?私はそれらを削除すると、クエリは正常に動作することを知っています。私は私の質問は、私が得るエラーを与えられたと思う?私のパラメータの近くにこれらの奇妙な `シンボルがないようにquerybuild CakePHPコードを変更するにはどうすればいいですか?

答えて

0

CakePHPがエイリアスの周りに一重引用符を追加すると、私は驚くでしょう。あなたはMySQLを使用しているようですので、私はtimestampをバッククォート(デフォルトの引用符)で囲むことを期待しています。

自動引用符を有効にしているため、選択リストの文字列値は引用符で囲まれた識別子であると予想されるため、SQLスニペットにバッククォートが追加されています。明らかに、これは非識別子でうまく機能しません。

あなたはSQLスニペットを使用する場合は、あなたが表現は次のように、文字列の代わりにオブジェクトとして渡す必要があります。

->select(function (\Cake\ORM\Query $query) { 
    return [ 
     'timestampdiff' => $query->newExpr(
      'TIMESTAMPDIFF(SECOND, Posts.post_date, Answers.answer_date)' 
     ) 
    ]; 
}) 

いっそtranspilableを生産関数ビルダーを使用して、それらを構築し、自動互換性のある表現をautoquoting:あなたは正しくセットアップの関連付けをした場合ところで

[ 
    'timestampdiff' => $query->func()->TIMESTAMPDIFF([ 
     'SECOND' => 'literal', 
     'Posts.post_date' => 'identifier', 
     'Answers.answer_date' => 'identifier' 
    ]) 
] 

、次の2つの基本的なinnerJoinWith()の代わりに使用することができ、これらすべてのマニュアルは、加入:

->innerJoinWith('Questions.Tags') 
->innerJoinWith('Questions.Posts') 

参照完璧だったにも

+0

ねえ@ndm!ちょうど私が必要なもの!払い戻しのためにありがとう! – Matthew

+0

ようこそ。私が 'select()'メソッドのコールバックを使用するように質問を更新したので、クエリ生成を分割する必要はありません。 @マチュー – ndm