尝试在推进2中执行一个相当简单的查询。我有一个人桌和一个占有桌-人可以有许多占有物,但每种占有类型只有一个。所以一个人可以有一本书,一辆车,等等。我试图在Propel中编写一个查询,如果他们有车的话,这个查询将返回所有人及其车名。下面是代码和结果查询:

$x = PersonQuery::create()
  ->groupById()
  ->leftJoinPossession()
  ->addJoinCondition('Possession','Possession.possession_type = ?', 'car')
  ->withColumn('Possession.possession_name', 'CarName')
  ->where('Possession.possession_name IS NOT NULL')
  ->find()
  ->toString();

//resulting sql
SELECT person.id, possession.possession_name as CarName
FROM person
LEFT JOIN possession  ON (person.id=possession.person_id AND possession.possession_type = 'car')
WHERE possession.possession_name IS NOT NULL;

这和预期的一样。但是,我需要对拥有表执行多个连接(例如,为每个人获取书籍),因此需要使用别名。下面是我修改前一个查询以使用拥有表的别名(以及为每个人获取书本)时发生的情况:
$x = PersonQuery::create()
  ->groupById()
  ->leftJoinPossession('p')
  ->addJoinCondition('p','p.possession_type = ?', 'car')
  ->leftJoinPossession('p2')
  ->addJoinCondition('p2','p2.possession_type = ?', 'book')
  ->withColumn('p.possession_name', 'CarName')
  ->withColumn('p2.possession_name', 'BookName')
  ->where('p.possession_name IS NOT NULL')
  ->find()
  ->toString();

//resulting sql
SELECT person.id, p.possession_name as CarName, p2.possession_name as BookName
FROM person
CROSS JOIN possession
LEFT JOIN possession p ON (person.id=p.person_id AND p.possession_type = 'car')
LEFT JOIN possession p2 ON (person.id=p2.person_id AND p2.possession_type = 'book')
WHERE p.possession_name IS NOT NULL;

如您所见,出于某种原因,pullep在查询中添加了“交叉连接拥有”。这不会更改查询的结果,但会使查询速度非常慢。有什么想法可以告诉Propel不要使用交叉连接,同时仍然使用连接表的别名吗?(如果我去掉“where”子句,交叉连接也会消失)

最佳答案

你为什么要留下来?如果我正确地理解了你的帖子,你只想得到那些真正有车的人的结果。因此,以下方法应该有效:

PersonQuery::create()
  ->withColumn('Possession.possession_name', 'CarName')
  ->usePossessionQuery()
  ->filterByPossessionType('car')
  ->endUse()
  ->find()
  ->toString();

usexxquery()也可以被赋予一个别名,因此您应该能够完成相同的任务,但更容易:)
编辑:具有多个联接的示例,如第二个示例所示:
PersonQuery::create()
  ->withColumn('possession_car.possession_name', 'CarName')
  ->withColumn('possession_book.possession_name', 'BookName')
  ->usePossessionQuery('possession_car')
  ->filterByPossessionType('car')
  ->endUse()
  ->usePossessionQuery('possession_book')
  ->filterByPossessionType('book')
  ->endUse()
  ->find()
  ->toString();

关于php - 当对JOIN表使用别名时,Propel将CROSS JOIN添加到查询中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40116385/

10-09 23:29
查看更多