2017-08-01 12 views
0

特定のパラメータを持つ別のテーブルに請求書IDが表示されない請求書の一覧を検索しようとしています。この問題は一日中私を悩ませています。私は存在していないではないのバリエーションを試してみた。ここ Sql to 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.id WHERE b.id IS NULL'の上でLEFT OUTER JOINからSELECT a.idを実行することです。これは機能的には「NOT IN」と同じですが、オプティマイザがより良いクエリプランを作成できるようにします。 – Shawn

+0

フィードバックありがとうございます。動作しているようですが、他のパラメータを追加するのに問題があります。私は何を試しても構文エラーが出てくる。 invoiceitem.class = 'ITEM' LEFT OUTER JOINをinvoiceitemを登録しよう 請求書FROM SELECT * invoice_history ON invoices.id = invoice_history.invidを​​invoice_history.invidが は私に構文エラーを与えNULLです。 – user2725545

+0

@Shawnあなたにタグをつけるのを忘れてしまった – user2725545

答えて

0

あなたの参加には参加条件がありません。追加しました。 NOT EXISTSと同じ効果を得るには、0とカウントを比較します。さらに、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

Hmm。このSQLクエリは私のために0の結果を返すようです。あなたの助けを本当にありがとう。私の質問のSQLは、実際に私に探していた正しい結果を与えました。私はそれをdqlに変換する必要があります。 – user2725545

関連する問題