好的,所以我有一个查询,我已经研究和研究如何让这个工作和我的生活,我不能!...也许我只是这样做错误和最小的信息ive发现..
我有一个名为timeclock setup的表..它有一个字段:noteBy_id,它是记录所属用户的id ...
我现在需要做的是系统中管理方面的事情。我预计有超过1家公司使用这个时钟系统,因此我需要根据公司ID过滤结果。在用户表中,我有一个名为parentcompany_id
所以,让我们看看我是否可以用语言表达我需要做的事情。
我需要从时钟中选择*并离开加入user.parentcompany_id,其中timeclock.daydate< :start和u.parentcompany =:pid
其中start是:`date('Y-m-d 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 != ''
在正常情况下会完美地工作......但在这方面,它只是没有...任何想法?
答案 0 :(得分:3)
我最近不得不这样做..我猜这是你的noteBy是用户表中的ManyToOne而你想让它过滤当前管理员公司的结果登录到你的系统..
因此,调整一个我必须自己写这个任务的连接很容易。我个人喜欢使用QueryBuilder,所以这将在查询构建器中完成..
您查询中的第一个错误是->from('timeclock', 't')
行。因为您之前使用$qb = $em->getRepository('EcsCrmBundle:TimeClock'); $qb = $qb->createQueryBuilder('t');
创建了对象,所以在查询构建器中不需要from
,因为它将为您生成。
接下来的问题是左边的问题,我会解释为什么当我向你展示工作版本时。
最后一个问题,即阻止它按你想要的方式工作 - 是一个缺失的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')
创建了对象,我们只需选择t
和u
对于连接,我们通过noteBy
列加入时钟表,该列是用户表中的用户ID。所以,第一个参数是“from”别名。因此,由于我们使用t为时钟表别名,我们使用t.noteBy
。 leftjoin中的下一个参数是第二个表的别名,在这种情况下是u
但是可以是任何东西..无论如何,leftJoin的第三个参数 - 是你加入它的方式..要么是{{ 1}}或WITH
将在这里工作。和第四个参数,是你希望它拥有的匹配......在这种情况下ON
你会看到我摆脱了u.id must equal t.noteBy
中的一个,我这样做是因为使用结构合理的查询你不应该需要它。然而,我确实为andWhere
添加了andWhere
,因为你想要过滤的是你应该在WHERE而不是在连接本身中匹配它。
文档在这方面非常有限,我花了一段时间才把它全部弄清楚..你,毫无疑问 - 像我一样,开始使用学说来手工编写你的查询。因此,你似乎刚刚开始使用Symfony(我现在约2个月),你仍然处于手工编码的心态。但是随着时间的推移,你将开始了解DQL的生活方式。试试这个问题,看看会发生什么。
答案 1 :(得分:0)
好的,首先您需要将实体Timeclock
与Company
相关联。每当您想要加入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
。
这是你想要达到的目标吗?