使用不存在或不存在的情况下的SQL到Dql

时间:2017-08-01 19:16:45

标签: sql dql not-exists notin

我试图找到一张发票​​列表,其中发票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

从我学到的东西中解决这个问题,没有“不存在”#34;在dql中(不要引用我的话),所以我一直试图使用&#34; Not In&#34;方法而不是。从本质上讲,这是我所有努力带给我的地方:

$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())));

感谢大家的帮助!

1 个答案:

答案 0 :(得分:0)

您的加入没有加入条件,我添加了一个。通过将0与计数进行比较,您可以获得与NOT EXISTS相同的效果。此外,不属于GROUP BY的所有列都必须应用聚合函数。

  SELECT invoices.id, max(invoices.depdate) as depdate
    FROM invoices JOIN invoiceitem ON (invoices.id= invoiceitem.id)
   WHERE invoiceitem.class = 'ITEM'
     AND invoices.rmlist >= $date1
     AND invoices.rmlist <= $date2
     AND 0 = 
             (SELECT count(*) c
                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 depdate ASC