【发布时间】:2018-01-08 19:17:08
【问题描述】:
我正在尝试查找发票 ID 未出现在具有某些参数的另一个表中的发票列表。这个问题整天困扰着我。我尝试过不存在和不存在的变体。
这是我最终想要实现的 sql:
SELECT * FROM invoices
JOIN invoiceitem
WHERE invoiceitem.class = 'ITEM'
AND invoices.rmlist >= $date1
AND invoices.rmlist <= $date2
AND NOT EXISTS (
SELECT * FROM invoice_history
WHERE invoices.id = invoice_history.invid
AND invoice_history.ttype = 'PR'
AND invoice_history.note = 'Vouchers Printed')
AND invoiceitem.voucherrequired = 1
GROUP BY invoices.id
ORDER BY invoices.depdate ASC
根据我所学到的试图弄清楚这一点,dql 中没有“不存在”(不要引用我的话),所以我一直在尝试使用“不存在”方法。从本质上讲,这就是我所有努力的结果:
$q2 = $em->createQueryBuilder()
->from('ClicctTravelBundle:InvoiceHistory', 'ih')
->Where("ih.ttype = 'PR'")
->andWhere("ih.note = 'Vouchers Printed'")
->groupBy('ih.invid');
$qb->leftJoin('i.history', 'h')
->where($qb->expr()->notExist('i.id', $q2->select('ih.invid')->getDQL()));
我做错了什么?感谢您的帮助!
[编辑]
我相信我已经解决了我的问题。这段代码似乎对我有用:
$qb = $em->createQueryBuilder()
->from('ClicctTravelBundle:Invoices', 'i')
->join('i.invoiceitems', 'b')
->select('i')
->Where("b.class = 'ITEM'")
->andWhere("i.rmlist >=:fdate")
->setParameter("fdate",$fromdate)
->andWhere("i.rmlist <=:tdate")
->setParameter("tdate",$todate)
->orderBy('i.depdate')
->groupBy('b.invoiceno');
$qb2 = $em->createQueryBuilder()
->select("h")
->from("ClicctTravelBundle:InvoiceHistory","h")
->andWhere("h.invid = i.id")
->andWhere("h.note = 'Vouchers Printed'");
$qb->andWhere($qb->expr()->not($qb->expr()->exists($qb2->getDQL())));
感谢大家的帮助!
【问题讨论】:
-
我不知道 DQL,所以我不确定你会怎么做,但我一直发现
NOT INs 效率非常低。如果您可以修改您的查询,一个更高效的方法是执行SELECT a.id FROM a LEFT OUTER JOIN b ON a.id = b.id WHERE b.id IS NULL。这在功能上与NOT IN相同,但允许优化器制定更好的查询计划。 -
感谢您的反馈。它似乎正在工作,但我在添加其他参数时遇到了麻烦。无论我尝试什么,我都会不断收到语法错误。 SELECT * FROM invoices JOIN invoiceitem WHERE invoiceitem.class= 'ITEM' LEFT OUTER JOIN invoice_history ON invoices.id = invoice_history.invid WHERE invoice_history.invid IS NULL 给我一个语法错误。
-
@Shawn 抱歉忘记给你加标签
-
我不确定 DQL 是否可以进行这样的 JOIN。虽然我不明白为什么它不能。由于这样的原因,我不是 ORM 的忠实粉丝。这应该是一个相对简单的查询,但是 ORM 使它变得更复杂一些。 :-/
标签: sql dql not-exists notin