gpt4 book ai didi

php - Propel 在使用别名连接表时添加 CROSS JOIN 查询

转载 作者:行者123 更新时间:2023-11-29 04:36:32 25 4
gpt4 key购买 nike

尝试在 Propel 2 中做一个相当简单的查询。我有一个 Person 表和一个 Possession 表——一个人可以拥有很多属性(property),但每种属性(property)类型只能有一个。所以一个人可以拥有 1 本书、1 辆车等。我正在尝试在 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;

这按预期工作。但是,我需要对 possession 表进行多次连接(例如,为每个人获取书籍),因此我需要使用别名。下面是当我修改前面的查询只是为了使用属性(property)表的别名(并且还为每个人获取书)时发生的情况:

$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;

如您所见,出于某种原因,Propel 在查询中添加了“CROSS JOIN possession”。这不会改变查询的结果,但会使其非常慢。关于如何告诉 Propel 不要使用 CROSS JOIN 同时仍然为我的联接表使用别名的任何想法? (如果我去掉 'where' 子句,CROSS JOIN 也会消失)

最佳答案

找到了解决此问题的方法。问题是,当我尝试对同一个表进行多个左连接(通过使用别名)时,Propel 也会包含对该表的交叉连接。但是,我发现如果第一个连接没有使用别名,Propel 不会添加交叉连接。

所以,总而言之,这是行不通的:

$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;

但这按预期工作:

$x = PersonQuery::create()
->groupById()
->leftJoinPossession() //changed
->addJoinCondition('Possession','Possession.possession_type = ?', 'car') //changed
->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
LEFT JOIN possession ON (person.id=posession.person_id AND posession.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;

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com