2017-08-01 48 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