1

好的,所以我有一个查询,我已经研究并研究了如何让它工作,而对于我的生活,我不能!...也许我只是做错了,我发现的信息很少..

我有一个名为 timeclock setup.. 的表,其中有一个字段:noteBy_id,它是记录所属用户的 id...

我现在需要做的是系统中事物的管理方面。我预计会有超过 1 家公司使用这个时钟系统,因此我需要根据公司 ID 过滤结果。在用户表中,我有一个名为parentcompany_id

所以,让我们看看我是否可以用语言表达我需要做的事情..

我需要从时钟中选择 * 并离开加入 user.parentcompany_id where timeclock.daydate < :start 和 where u.parentcompany = :pid

其中开始是:`date('Ymd 00:00:00');

我已经设置了这个查询:

$em = $this->getDoctrine()->getEntityManager();
$start = date('Y-m-d 00:00:00');
$qb = $em->getRepository('EcsCrmBundle:TimeClock');
$qb = $qb->createQueryBuilder('t');

$query = $qb->select('t, u.parentcompany_id')
->from('timeclock', 't')
->leftJoin('Ecs\AgentManagerBundle\Entity\User', 'u', 'ON' 'u.id = t.noteBy_id AND u.parentcompany_id = :pid')
->where('t.daydate < :start')
->andWhere("t.noteBy_id != ''")
->setParameter('start', $start)
->setParameter('pid', $user->getParentcompany())
->getQuery();

$entities = $query->getArrayResult();

我看了又看,找不到解决我得到的错误的方法:

An exception has been thrown during the rendering of a template ("[Semantical Error] line 0, col 112 near 'u ON u.id = t.noteBy_id': Error: Identification Variable Ecs\AgentManagerBundle\Entity\User used in join path expression but was not defined before.") in EcsCrmBundle:TimeClock:manager.html.twig at line 5.

得到输出的查询是:

SELECT t, u.parentcompany_id FROM Ecs\CrmBundle\Entity\TimeClock t LEFT JOIN Ecs\AgentManagerBundle\Entity\User u ON u.id = t.noteBy_id AND u.parentcompany_id = :pid, timeclock t LEFT JOIN Ecs\AgentManagerBundle\Entity\User u ON u.id = t.noteBy_id AND u.parentcompany_id = :pid WHERE t.daydate < :start AND t.noteBy_id != ''

在正常情况下它会完美地工作......但在这种情况下,它只是不......有什么想法吗?

4

2 回答 2

3

我最近不得不这样做..我猜你的noteBy是用户表中的ManyToOne,你想让它过滤当前登录到你的管理员公司的结果系统..

因此,为这样的任务调整我必须自己编写的连接很容易。我个人喜欢使用 QueryBuilder,所以这将在查询生成器中完成。

您查询中的第一个错误是该->from('timeclock', 't')行。因为您之前已经创建了对象,$qb = $em->getRepository('EcsCrmBundle:TimeClock'); $qb = $qb->createQueryBuilder('t');所以不需要from在查询构建器中,因为它将为您生成。

下一个问题是 leftJoin,当我向您展示工作版本时,我将解释原因。

最后一个问题,阻止它按你想要的方式工作 - 是一个缺失的andWhere条款。因此,让我们看一下一个有效的查询。

$query = $qb->select('t, u')
     ->leftJoin('t.noteBy', 'u', 'WITH', 'u.id = t.noteBy')
     ->where('t.daydate < :start')
     ->andWhere('u.parentcompany = :pid')
     ->setParameter('start', $start)
     ->setParameter('pid', $user->getParentcompany()) 
     ->getQuery();

所以因为我们已经通过使用创建了对象,所以$qb = $qb->createQueryBuilder('t')我们只需选择tu

对于连接,我们通过列连接时钟表,该noteBy列是用户表中的用户 ID。因此,第一个参数是“来自”别名。因此,由于我们使用 t 为时钟表起别名,我们使用t.noteBy. leftjoin 中的下一个参数是第二个表的别名,u在这种情况下,它可以是任何东西。无论如何,leftJoin 的第三个参数 - 是您加入它的方式.. 要么 aWITH要么ON将在这里工作。第四个参数是您希望它拥有的匹配项.. 在这种情况下u.id must equal t.noteBy

您会看到我删除了其中一个andWhere,我这样做是因为使用结构正确的查询您不需要它。但是,我确实添加了andWherefor,u.parentcompany因为毕竟这是您要过滤的内容,您应该将其放在 WHERE 中,而不是作为连接本身的匹配项。

文档在这方面非常有限,我也花了一段时间才弄清楚。毫无疑问,你和我一样,是通过手工编写查询来使用学说的。因此,由于您似乎刚刚开始使用 Symfony(我自己也是现在大约 2 个月),您仍然处于手动编码的心态。但随着时间的推移,您将开始了解 DQL 的生活方式。试试这个查询,看看会发生什么。

于 2012-04-05T02:08:01.980 回答
0

好的,首先您需要将实体TimeclockCompany. 每当您想加入两个实体时,Doctrine它们都需要通过某些属性(即表列)相关联。

我认为此查询中不需要User实体,因为所有信息都可以通过Company实体获得,并且您没有根据任何用户属性过滤结果。

您想要的查询应该看起来像这样(或多或少)。我冒昧地_id从实体属性中删除了后缀,因为它们往往会掩盖真正发生的事情。;)

$query = $this->getEntityManager()->createQuery("SELECT t, c.id FROM EcsCrmBundle:TimeClock t JOIN t.company c WHERE c.id = :pid AND t.daydate < :start AND t.noteBy != ''");

$query->setParameter('start', $start);
$query->setParameter('pid', $user->getParentcompany());
return $query->getArrayResult();

另外,我做了inner-join( ),因为我认为没有它的陪伴就不可能有时钟,但如果它更适合你,请JOIN随意更改。LEFT JOIN

这是你想要达到的目标吗?

于 2012-04-04T23:36:08.903 回答