如何在Doctrine中重写具有许多条件的多个左联接

时间:2019-05-10 13:44:35

标签: mysql doctrine-orm doctrine

我不希望您在此Q上花费很多时间。但是,我感到在构建此查询时我犯了一个大错误并错过了一些东西。看起来像:

SELECT attributes, attributes_associations, COUNT(DISTINCT(products.id)) as count, attribute_groups, group_modifiers, linked_groups, linked_group_modifiers, attribute_linked_groups, attribute_category 
FROM App\Component\Attribute\Entity\Attribute attributes 
LEFT JOIN attributes.associations attributes_associations 
INNER JOIN attributes.products products 
LEFT JOIN attributes.group attribute_groups 
LEFT JOIN attribute_groups.modifiers group_modifiers 
LEFT JOIN attribute_groups.reverseLinkedGroups linked_groups 
LEFT JOIN linked_groups.modifiers linked_group_modifiers 
LEFT JOIN attributes.linkedGroups attribute_linked_groups 
LEFT JOIN attribute_groups.attributeConditions attribute_groupsattribute_conditions 
LEFT JOIN linked_groups.attributeConditions linked_groupsattribute_conditions 
LEFT JOIN attribute_groups.groupConditions group_conditions 
LEFT JOIN group_conditions.attributes group_conditions_attributes 
LEFT JOIN group_conditions.linkedGroup group_linked_group_conditions 
LEFT JOIN group_linked_group_conditions.attributes group_linked_group_conditions_attributes 
LEFT JOIN linked_groups.groupConditions linked_group_conditions 
LEFT JOIN linked_group_conditions.attributes linked_group_conditions_attributes 
LEFT JOIN linked_group_conditions.linkedGroup reverse_linked_group_conditions 
LEFT JOIN reverse_linked_group_conditions.attributes reverse_linked_group_conditions_attributes 
LEFT JOIN attribute_groups.category attribute_category 
LEFT JOIN attribute_linked_groups.category attribute_linked_category 
LEFT JOIN linked_groups.category linked_category 
WHERE attributes.isVisible = :attributeIsVisible AND products.isVisible = :productIsVisible 
AND products.price > :priceMin AND products.price < :priceMax 
AND (
    (
        (attribute_groupsattribute_conditions.id IN(:attributes) AND attribute_groups.conditionType = :conditionAnd) 
        OR ((attribute_groupsattribute_conditions.id IN(SELECT attribute_groupsattribute FROM App\Component\Attribute\Entity\Attribute attribute_groupsattribute 
        WHERE attribute_groupsattribute.id = :attribute_groups0 OR attribute_groupsattribute.id = :attribute_groups1 OR attribute_groupsattribute.id = :attribute_groups2 OR attribute_groupsattribute.id = :attribute_groups3 OR attribute_groupsattribute.id = :attribute_groups4 OR attribute_groupsattribute.id = :attribute_groups5)) 
AND attribute_groups.conditionType = :conditionOr)) 
OR attribute_groupsattribute_conditions IS NULL) 
AND (((linked_groupsattribute_conditions.id IN(:attributes) 
AND linked_groups.conditionType = :conditionAnd) 
OR ((linked_groupsattribute_conditions.id IN(SELECT linked_groupsattribute 
FROM App\Component\Attribute\Entity\Attribute linked_groupsattribute 
WHERE linked_groupsattribute.id = :linked_groups0 
OR linked_groupsattribute.id = :linked_groups1 
OR linked_groupsattribute.id = :linked_groups2 
OR linked_groupsattribute.id = :linked_groups3 
OR linked_groupsattribute.id = :linked_groups4 
OR linked_groupsattribute.id = :linked_groups5)) 
AND linked_groups.conditionType = :conditionOr)) OR linked_groupsattribute_conditions IS NULL) 
AND (group_conditions_attributes.id IN(:attributes) OR group_conditions_attributes IS NULL) 
AND (group_linked_group_conditions_attributes.id IN(:attributes) OR group_linked_group_conditions_attributes IS NULL) 
AND (linked_group_conditions_attributes.id IN(:attributes) OR linked_group_conditions_attributes IS NULL) 
AND (reverse_linked_group_conditions_attributes.id IN(:attributes) OR reverse_linked_group_conditions_attributes IS NULL) 
AND (attribute_category.id = :attributeCategory OR attribute_linked_category.id = :attributeCategory OR linked_category.id = :attributeCategory) 
AND (products.id IN(SELECT p40 FROM App\Component\Product\Entity\Product p40 INNER JOIN p40.attributes filters40 WHERE filters40 = 341 OR attribute_groups.id = :group40)) 
AND (products.id IN(SELECT p44 FROM App\Component\Product\Entity\Product p44 INNER JOIN p44.attributes filters44 WHERE filters44 = 374 OR attribute_groups.id = :group44)) 
AND (products.id IN(SELECT p76 FROM App\Component\Product\Entity\Product p76 INNER JOIN p76.attributes filters76 WHERE filters76 = 950 OR attribute_groups.id = :group76)) 
AND (products.id IN(SELECT p77 FROM App\Component\Product\Entity\Product p77 INNER JOIN p77.attributes filters77 WHERE filters77 = 952 OR attribute_groups.id = :group77)) 
AND products.id IN(SELECT product_department FROM App\Component\Product\Entity\Product product_department INNER JOIN product_department.attributes filters1002  WHERE filters1002.id = :filter1002)
GROUP BY attributes.id, attributes_associations.id, attribute_groups.id, group_modifiers.id, linked_groups.id, linked_group_modifiers.id, attribute_linked_groups.id, attribute_groupsattribute_conditions.id, linked_groupsattribute_conditions.id 
ORDER BY count DESC, attributes.name ASC

这是一个按产品属性,属性组和属性类别进行过滤的查询。在没有失去其重要部分的情况下,我无法简化此查询。主要问题是运行此查询需要60秒钟。好吧,我的行数少于一百。我不能指望查询运行大约2分钟。

我需要Doctrine支持左连接,以便当我使用$attribute->getGroup()时不会进行新查询。此外,在某些情况下我无法避免左联接,因为联接表上有条件。

我找到了这篇文章https://www.colinodell.com/blog/201703/limiting-subqueries-doctrine-2-dql。但是仅在join子查询中仅选择一行时才有效。而且,Doctrine不会将子查询的结果用作适当的实体关系。

如果我错过了一些细节,请告诉我。

0 个答案:

没有答案