在CakePHP的控制器中,我试图找出两个日期之间的区别。以下是我知道在传统SQL中工作的常规查询。
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();
现在这里是错误发挥作用的地方。当我执行CakePHP控制器代码时,我得到了这个:
“错误:SQLSTATE [42000]:语法错误或访问冲突:1064,您的SQL语法中有错误;请查看与您的MariaDB服务器版本对应的手册,以便在'SECOND,Posts附近使用正确的语法。 post_date,Answers.answer_date')AS'staystampdiff'FRN'答案'在第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 :(得分:0)
如果CakePHP会在别名周围添加单引号,我会感到惊讶。您似乎正在使用MySQL,因此我希望将timestamp
括在反引号中(默认引号字符)。
您的SQL代码段添加了反引号,因为您启用了自动引用,并且选择列表中的字符串值应该是引用的标识符。显然,这与非标识符无关。
如果要使用SQL代码段,则需要将它们作为表达式对象而不是字符串传递,例如:
->select(function (\Cake\ORM\Query $query) {
return [
'timestampdiff' => $query->newExpr(
'TIMESTAMPDIFF(SECOND, Posts.post_date, Answers.answer_date)'
)
];
})
或者更好的是使用函数构建器构建它们,它可以生成可传输的,自动自动调整的兼容表达式:
[
'timestampdiff' => $query->func()->TIMESTAMPDIFF([
'SECOND' => 'literal',
'Posts.post_date' => 'identifier',
'Answers.answer_date' => 'identifier'
])
]
顺便说一句,如果您已正确设置关联,则可以使用两个基本innerJoinWith()
而不是所有这些手动连接:
->innerJoinWith('Questions.Tags')
->innerJoinWith('Questions.Posts')
另见