我正在开发我的第一个symfony应用程序,在尝试使用queryBuilder时,我已经在几个小时内遇到问题。
我尝试执行SQL查询,但收到以下错误:
request.CRITICAL:未捕获的PHP异常Doctrine \ ORM \ Query \ QueryException:" [语义错误]第0行,第288行附近' FROM StatsBundle \ Entity \ PlayerRealMatch':错误:Class& #39; FROM'未定义。"
基本上我存储了足球运动员的评分和目标,现在我想用总和和平均数来检索它的聚合。
我在服务中,并且我在我的PlayerRealMatchRepository中调用了一个方法,该方法的核心代码如下:
$qb = $this->createQueryBuilder('prm');
$qb->select(
"SUM(prm.has_started) as tit,
SUM(prm.has_entered) as rempl,
SUM(prm.yellow_cards) as yc,
SUM(prm.red_card) as rc,
SUM(prm.goals) AS gf,
SUM(prm.own_goals) as ga,
AVG(prm.rating) as avg"
)
->innerJoin('prm.realMatch', 'rm')
->where('prm.playerId = :idPlayer')
->groupBy('rm.season')
->setParameter('idPlayer', $player->getId())
->getQuery();
$query =$qb->getQuery();
$seasonData = $query->getResult();
如果我用调试器查看$ query对象的_dql属性,请查看我的内容:
SELECT SUM(prm.has_started) as tit,
SUM(prm.has_entered) as rempl,
SUM(prm.yellow_cards) as yc,
SUM(prm.red_card) as rc,
SUM(prm.goals) AS gf,
SUM(prm.own_goals) as ga,
AVG(prm.rating) as avg
FROM StatsBundle\Entity\PlayerRealMatch prm
INNER JOIN prm.realMatch rm
WHERE prm.playerId = :idPlayer
GROUP BY rm.season
对我来说看起来并不坏,你们对这里的错误有任何疑问吗?
注意:这是我试图实现的查询示例,它可以直接在我的数据库上完美运行:
SELECT SUM(prm.has_started) as tit,
SUM(prm.has_entered) as rempl,
SUM(prm.yellow_cards) as yc,
SUM(prm.red_card) as rc,
SUM(prm.goals) AS gf,
SUM(prm.own_goals) as ga,
AVG(prm.rating) as avg
FROM player_real_match prm
INNER JOIN real_match rm ON prm.real_match_id = rm.id
WHERE prm.player_id = 327
GROUP BY rm.season;
以下详细信息
3个实体:
以下是各自配置的摘录,以显示它们之间的关联方式。
StatsBundle\Entity\Player:
...
manyToOne:
real_team:
targetEntity: RealTeam
inversedBy: players
joinColumn:
onDelete: CASCADE
name: real_team_id
referencedColumnName: id
oneToMany:
player_real_matches:
targetEntity: PlayerRealMatch
mappedBy: player
...
StatsBundle\Entity\RealMatch:
...
home_team:
targetEntity: RealTeam
inversedBy: home_matches
joinColumn:
onDelete: CASCADE
name: home_team_id
referencedColumnName: id
away_team:
targetEntity: RealTeam
inversedBy: away_matches
joinColumn:
onDelete: CASCADE
name: away_team_id
referencedColumnName: id
oneToMany:
player_real_matches:
targetEntity: PlayerRealMatch
mappedBy: real_match
...
StatsBundle\Entity\PlayerRealMatch:
...
manyToOne:
real_match:
targetEntity: RealMatch
inversedBy: player_real_matches
joinColumn:
onDelete: CASCADE
name: real_match_id
referencedColumnName: id
player:
targetEntity: Player
inversedBy: player_real_matches
joinColumn:
onDelete: CASCADE
name: player_id
referencedColumnName: id
...
从服务
调用存储库方法 foreach ($players as $player) {
$this->aggregatePlayerData($player, $match);
}
private function aggregatePlayerData(Player $player, RealMatch $match)
{
$playerStats = $this->_em
->getRepository('StatsBundle:PlayerRealMatch')
->getAggregatedStats($player, $match);
}
public function __construct(EntityManager $entityManager)
{
$this->_em = $entityManager;
}
这是关于我的服务的services.yml
stats.aggregator:
class: StatsBundle\Service\Aggregator
arguments: [ "@doctrine.orm.entity_manager"]
存储库方法
/**
* getAggregatedStats
*
* @param $player the player entity
* @param RealMatch $match the real match entity
*
* @return array
*/
public function getAggregatedStats($player, RealMatch $match)
{
$qb = $this->createQueryBuilder('prm');
$qb->select(
"SUM(prm.has_started) as tit,
SUM(prm.has_entered) as rempl,
SUM(prm.yellow_cards) as yc,
SUM(prm.red_card) as rc,
SUM(prm.goals) AS gf,
SUM(prm.own_goals) as ga,
AVG(prm.rating) as avg"
)
->from('StatsBundle:PlayerRealMatch', 'prm')
->innerJoin('prm.realMatch', 'rm')
->where('prm.playerId = :idPlayer')
->groupBy('rm.season')
->setParameter('idPlayer', $player->getId())
->getQuery();
$query = $qb->getQuery();
$seasonData = $query->getResult();
return $seasonData;
}
对于这篇长篇文章感到抱歉,我试图尽可能清楚地记录它。 非常感谢你的帮助!
答案 0 :(得分:4)
您正在尝试使用保留的sql字作为列名, 尝试改变
"AVG(prm.rating) as avg" -> "AVG(prm.rating) as avgRating"
答案 1 :(得分:0)
我终于找到了这个问题,我相信这是一个经典的初学者的错误:
在我的select指令中,我使用的是lower_case属性,因为这是我的SQL列格式化的方式。
然而,这不是我的实体属性的情况。所以这是我的选择指令的正确语法
"SUM(prm.hasStarted) as tit,
SUM(prm.hasEntered) as rempl,
SUM(prm.yellowCards) as yc,
SUM(prm.redCard) as rc,
SUM(prm.goals) as gf,
SUM(prm.ownGoals) as ga,
AVG(prm.rating) as avg"
所以结论是:在执行DQL时,始终引用实体属性而不是数据库列。
错误信息虽然很奇怪,但我会喜欢更明确的内容,例如“实体X没有属性Y”
非常感谢Azam Alvi。
答案 2 :(得分:-1)
您在查询中没有从字段中提供尝试这样做
$qb = $this->createQueryBuilder('prm');
$qb->select(
"SUM(prm.has_started) as tit,
SUM(prm.has_entered) as rempl,
SUM(prm.yellow_cards) as yc,
SUM(prm.red_card) as rc,
SUM(prm.goals) AS gf,
SUM(prm.own_goals) as ga,
AVG(prm.rating) as avg"
)
->from('StatsBundle:PlayerRealMatch ', 'prm') // this one is missing
->innerJoin('prm.realMatch', 'rm')
->where('prm.playerId = :idPlayer')
->groupBy('rm.season')
->setParameter('idPlayer', $player->getId());
$seasonData = $qb->getQuery()->getResult();