【问题标题】:Doctrine INNER/LEFT JOIN two tablesDoctrine INNER/LEFT JOIN 两张表
【发布时间】:2013-06-14 18:37:05
【问题描述】:

I am learning from this Question but facing issues with many operations in between:

doctrine 2 query builder and join tables

以下是我的问题。我也在寻求上一个问题的帮助。感谢那些帮助我解决问题的人。

我在 Doctrine 2.3 中创建一个大查询,操作对我来说并不熟悉。但是我在很多人的帮助下学会了。目前,我正面临 3 个表之间的内部连接问题。

我的关节:

SELECT *
FROM user AS u
LEFT JOIN source AS s ON u.user_source_fk=s.source_id
LEFT JOIN area AS a ON s.source_node_fk = a.area_id;

上面的查询是我试图在 Doctrine 中转换的。

我试图像这样给出查询,但它不起作用:

SELECT a FROM Ipf\Model\User u LEFT JOIN Ipf\Model\Sources ON u.user_source_fk=s.source_id LEFT JOIN Ipf\Model\Area aa ON s.source_node_fk = aa.area_id;

我的原始查询将如何:

1 Doctrine JOIN 查询:

SELECT *
FROM user AS u
LEFT JOIN source AS s ON u.user_source_fk=s.source_id
LEFT JOIN area AS a ON s.source_node_fk = a.area_id;

+

SELECT * FROM user WHERE 
(`user_name` like '%TOM%' OR `user_name` like '%AN%' and `login_datetime` BETWEEN '2013-01-01 00:00:00' and '2013-02-31 23:59:59') OR
NOT ( --NOR
   (`user_name` like '%PHP%' OR `user_name` like '%BA%' and `login_datetime` BETWEEN '2013-02-01 00:00:00' and '2013-03-31 23:59:59') OR
   (`user_name` like '%SUN%' OR `user_name` like '%MOON%' and `login_datetime` BETWEEN '2013-03-01 00:00:00' and '2013-04-31 23:59:59')
) OR
NOT ( --NAND
   (`user_name` like '%RAJ%' OR `user_name` like '%MUTH%' and `login_datetime` BETWEEN '2013-04-01 00:00:00' and '2013-06-31 23:59:59') AND
   (`user_name` like '%BAG%' OR `user_name` like '%LAP%' and `login_datetime` BETWEEN '2013-05-01 00:00:00' and '2013-07-31 23:59:59')
)

我想用上面的查询对查询做内联,即与运算符Refer:Multiple Query in Doctrine with NAND,NOR,NOT,AND Operators 的内联

如何加入表并执行查询?

2 学说查询生成:

$qry = $this->manager()->createQueryBuilder()
        ->from($this->entity, 'e')
        ->select('e');


// (`user_name` like '%TOM%' OR `user_name` like '%AN%' and `login_datetime` BETWEEN '2013-01-01 00:00:00' and '2013-02-31 23:59:59')
$expr1 = $qry->expr()->andX(
    $qry->expr()->orX(
       $qry->expr()->like('e.user_name', '%TOM%'), 
       $qry->expr()->like('e.user_name', '%AN%')
    ),
    $qry->expr()->between('e.login_datetime', '2013-02-01 00:00:00', '2013-02-31 23:59:59')
);

//(`user_name` like '%PHP%' OR `user_name` like '%BA%' and `login_datetime` BETWEEN '2013-02-01 00:00:00' and '2013-03-31 23:59:59')

$expr2a = $qry->expr()->andX(
    $qry->expr()->orX(
       $qry->expr()->like('e.user_name', '%PHP%'), 
       $qry->expr()->like('e.user_name', '%BA%')
    ),
    $qry->expr()->between('e.login_datetime', ''2013-02-01 00:00:00'', '2013-03-31 23:59:59')
);

// (`user_name` like '%SUN%' OR `user_name` like '%MOON%' and `login_datetime` BETWEEN '2013-03-01 00:00:00' and '2013-04-31 23:59:59')
$expr2b = $qry->expr()->andX(
    $qry->expr()->orX(
       $qry->expr()->like('e.user_name', '%SUN%'), 
       $qry->expr()->like('e.user_name', '%MOON%')
    ),
    $qry->expr()->between('e.login_datetime', '2013-03-01 00:00:00', '2013-04-31 23:59:59')
);

// combine expr2a and expr2b with OR as $expr2

$expr2 = $qry->expr()->orX($expr2a, $expr2b);


// (`user_name` like '%RAJ%' OR `user_name` like '%MUTH%' and `login_datetime` BETWEEN '2013-04-01 00:00:00' and '2013-06-31 23:59:59')

$expr3a = $qry->expr()->andX(
    $qry->expr()->orX(
       $qry->expr()->like('e.user_name', '%RAJ%'), 
       $qry->expr()->like('e.user_name', '%MUTH%')
    ),
    $qry->expr()->between('e.login_datetime', ''2013-04-01 00:00:00'', '2013-06-31 23:59:59')
);

// (`user_name` like '%BAG%' OR `user_name` like '%LAP%' and `login_datetime` BETWEEN '2013-05-01 00:00:00' and '2013-07-31 23:59:59')
$expr3b = $qry->expr()->andX(
    $qry->expr()->orX(
       $qry->expr()->like('e.user_name', '%BAG%'), 
       $qry->expr()->like('e.user_name', '%LAP%')
    ),
    $qry->expr()->between('e.login_datetime', '2013-05-01 00:00:00', '2013-07-31 23:59:59')
);

// combine expr2a and expr2b with OR as $expr2

$expr3 = $qry->expr()->andX($expr3a, $expr3b);


// final query essentially WHERE expr1 OR NOT(expr2) OR NOT(expr3)
$qry->where($expr1)
    ->or($qry->expr()->not($expr2))
    ->or($qry->expr()->not($expr3));

如何通过JOIN操作修改实现上述查询?

谁能帮我解决我的问题。它在教义上对我来说是一场噩梦......

【问题讨论】:

    标签: orm doctrine-orm doctrine doctrine-1.2 doctrine-query


    【解决方案1】:

    您查询的复杂部分实际上是WHERE,因此您应该能够毫无问题地添加连接。

    $qry = $this->manager()->createQueryBuilder()
            ->select(array('e', 's', 'a'))
            ->from($this->entity, 'e')
            ->leftJoin('e.sources', 's')
            ->leftJoin('s.node', 'a');
    

    然后您将按原样执行其余的查询逻辑。

    需要提到的一件事是,在 DQL 中,您处理的是实体及其属性,而不是表和列。

    所以在我的示例中,e.sources 需要是您的 User 实体上的 UserSource 实体/集合的映射属性名称。同样,s.node 需要是Area 实体/集合在UserSource 上的映射属性名称。

    【讨论】:

    • 这也意味着我需要在 XML Mapping 中将两个表联合起来,或者我可以创建查询并运行?
    • 我在 Doctrine 中看到了可能的关节一对一、一对多、多对多、双向?我有什么想要改变的吗?
    • 我不知道你没有发布你的模型......这是评估它所必需的。但通常是的,如果您使用的是 ORM,那么您应该定义适当的映射。如果您只是使用 DBAL,那就另当别论了。
    • 我正在使用由 Zend/Doctrine 专家创建的任何现有应用程序.. 他们正在使用许多让我感到困惑的功能.. 但直到现在我还没有遇到任何 DBAL.. 我的供您参考的模块,我仍然面临问题的 XML 映射是 stackoverflow.com/questions/16917684/…
    • 同样上面的查询应该找到在同一查询stackoverflow.com/questions/17079748/…中找到的有限制的结果数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    • 1970-01-01
    • 2013-01-25
    • 2014-10-31
    • 1970-01-01
    • 2021-11-21
    相关资源
    最近更新 更多