我试图使查询使用case语句,并且无法弄清楚如何获取case以返回列值而不是常量。我的查询工作正常,只是我为结果提供的列名被Cake引用或以其他方式处理不当,或者可能是PDO在某个无法深入了解的层中的某个地方。我和bindValue差不多,但是我遇到的任何文档都没有告诉我如何做到这一点。
我发现此示例注释:
$statement->bindValue(1, 'a title'); $statement->bindValue(2, 5, PDO::INT); $statement->bindValue('active', true, 'boolean'); $statement->bindValue(5, new \DateTime(), 'date');
但在所有这些情况下,提供的值都是一个常数。我需要传递一个字符串,该字符串是我要返回的列的名称。
我尝试了两者'string'(导致加引号的列名)和'integer'(导致了0)。我尝试过PDO::FETCH_COLUMN(看起来不太可能,但是看起来像是http://php.net/manual/en/pdo.constants.php的下一个最佳选择,并且容易尝试…)。我尝试过'literal',受可将文字字符串放入表达式中的启发(导致Error: unknown type "literal")。该错误消息导致我无法正常运行src/Database/Type.php,但是那里也没有任何帮助。
'string'
'integer'
PDO::FETCH_COLUMN
'literal'
Error: unknown type "literal"
src/Database/Type.php
所以,我很困惑。这是我拥有的代码的简单版本(省略了一些条件和不相关的列):
$query = $this->Games->find(); $team_id = $query->newExpr()->addCase( [$query->newExpr()->eq('Games.status', 'home_default')], ['home_team_id', 'away_team_id'], ['string', 'string'] ); $defaulting = $query ->select([ 'id' => $team_id, 'count' => 'COUNT(Games.id)', ]) ->where([ 'Games.status IN' => ['home_default', 'away_default'], ]) ->group('id') ->toArray();
这将生成此SQL:
SELECT (CASE WHEN Games.status = 'home_default' THEN 'home_team_id' ELSE 'away_team_id' END) AS `id`, COUNT(Games.id) AS `count` FROM games Games WHERE Games.status in ('home_default','away_default') GROUP BY id
请注意,THEN 'home_team_id' ELSE 'away_team_id' END应该简单THEN home_team_id ELSE away_team_id END。然后,这将允许我读取已默认游戏的球队的ID列表以及其默认游戏的数量。
THEN 'home_team_id' ELSE 'away_team_id' END
THEN home_team_id ELSE away_team_id END
默认情况下,传递给的第二个参数的值QueryExpression::addCase()将被视为转换为 文字值 ,而不是 标识符 。如果需要后者,则应使用表达式IdentifierExpression。
QueryExpression::addCase()
IdentifierExpression
use Cake\Database\Expression\IdentifierExpression; // ... $team_id = $query->newExpr()->addCase( [ $query->newExpr()->eq('Games.status', 'home_default') ], [ new IdentifierExpression('Games.home_team_id'), new IdentifierExpression('Games.away_team_id') ] );
在这种情况下,也请忽略第三个参数,您不希望这些值是字符串文字(对于表达式,无论如何都将忽略类型)。