2017-08-01 95 views
0

我试图找到发票清单,其中发票ID不会出现在具有某些参数的另一个表中。这个问题一直在困扰我整天。我试过的变化不存在的,而不是Sql到Dql使用不在或不存在

这里是我最终想要达到的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中不要引用),所以我一直试图使用”Not In“方法。本质上,这是我所有的努力带给我的地方:

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

感谢大家的帮忙!

+0

我不知道DQL,所以我不知道你会怎么做,但我总是发现'NOT IN's是_very_inefficient。如果你可以修改你的查询,一个更高性能的方法是做'从左外连接选择a.id b在a.id = b.id WHERE b.id是NULL'。这在功能上与'NOT IN'相同,但允许优化器制定更好的查询计划。 – Shawn

+0

感谢您的反馈。它似乎工作,但我无法添加我的其他参数。无论我尝试什么,我都会收到语法错误。 SELECT * FROM JOIN invoiceitem WHERE invoiceitem.class = '项' LEFT OUTER JOIN发票invoice_history ON invoices.id = invoice_history.invid WHERE invoice_history.invid IS NULL 给我一个语法错误。 – user2725545

+0

@Shawn很抱歉忘记标记你 – user2725545

回答

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 
+0

嗯。这个SQL查询似乎为我返回0结果。非常感谢你的帮助。我的问题中的SQL实际上给了我正在寻找的正确结果。我只需要把它变成dql。 – user2725545