LEFT OUTER JOIN和NOT EXISTS查询

时间:2013-03-14 12:39:00

标签: sql sql-server-2005 left-join

我很难使用复杂的连接,我需要加入两个相同的两个表,并确保每次只使用特定记录(最新的)连接。

SELECT c.collection_id      AS collections, 
       s.strat_id           AS StrategyId, 
       s.strat_version      AS StrategyVersion, 
       ssb.side_ordering    AS SSB_SO, 
       ssb2.side_ordering   AS SSB2_SO, 
       Invoice1.invoice_id  AS Inv1ID, 
       Invoice2.invoice_id  AS Inv2ID, 
       Invoice1.printeddate AS Inv1PrintedDate, 
       Invoice2.printeddate AS Inv2PrintedDate 
  FROM dbo.collections AS c 
       INNER JOIN dbo.strategies AS s 
               ON c.collection_id = s.collection_id 
       INNER JOIN dbo.side_strat_brkrgs AS ssb 
               ON s.collection_id = ssb.collection_id 
                  AND s.strat_id = ssb.strat_id 
                  AND s.strat_version = ssb.strat_version 
       INNER JOIN dbo.strat_sides AS ss 
               ON ss.strat_side_id = ssb.strat_side_id 
       LEFT OUTER JOIN dbo.side_strat_brkrgs AS ssb2 
                    ON ssb2.collection_id = ssb.collection_id 
                       AND ssb2.strat_id = ssb.strat_id 
                       AND ssb2.strat_version = ssb.strat_version 
                       AND ssb2.side_ordering <> ssb.side_ordering 
       INNER JOIN dbo.strat_sides AS ss2 
               ON ss2.strat_side_id = ssb2.strat_side_id 
       LEFT OUTER JOIN dbo.newinvoiceitem AS InvoiceItem1 
                    ON ssb.collection_id = InvoiceItem1.collection_id 
                       AND ssb.side_ordering = InvoiceItem1.side_ordering 
                       AND s.strat_id = InvoiceItem1.strat_id 
       LEFT OUTER JOIN dbo.newinvoice AS Invoice1 
                    ON Invoice1.invoice_id = InvoiceItem1.invoice_id 
       LEFT OUTER JOIN dbo.newinvoiceitem AS InvoiceItem2 
                    ON ssb2.collection_id = InvoiceItem2.collection_id 
                       AND ssb2.side_ordering = InvoiceItem2.side_ordering 
                       AND s.strat_id = InvoiceItem2.strat_id 
       LEFT OUTER JOIN dbo.newinvoice AS Invoice2 
                    ON Invoice2.invoice_id = InvoiceItem2.invoice_id 
 WHERE NOT EXISTS (SELECT 1 
                     FROM dbo.newinvoiceitem tempInvoiceItem1 
                          INNER JOIN dbo.newinvoice AS tempInvoice1 
                                  ON tempInvoice1.invoice_id = 
                                     tempInvoiceItem1.invoice_id 
                    WHERE tempInvoiceItem1.collection_id = ssb.collection_id 
                          AND ssb.side_ordering = tempInvoiceItem1.side_ordering 
                          AND s.strat_id = tempInvoiceItem1.strat_id 
                          AND s.strat_version = tempInvoiceItem1.strat_version 
                          AND tempInvoice1.printeddate > Invoice1.printeddate) 
       AND NOT EXISTS (SELECT 1 
                         FROM dbo.newinvoiceitem tempInvoiceItem2 
                              INNER JOIN dbo.newinvoice AS tempInvoice2 
                                      ON tempInvoice2.invoice_id = 
                                         tempInvoiceItem2.invoice_id 
                        WHERE 
               tempInvoiceItem2.collection_id = ssb2.collection_id 
               AND ssb2.side_ordering = tempInvoiceItem2.side_ordering 
               AND s.strat_id = tempInvoiceItem2.strat_id 
               AND s.strat_version = tempInvoiceItem2.strat_version 
               AND tempInvoice2.printeddate > Invoice2.printeddate) 
       AND c.collection_id = 16447 

我获得了以下结果:

16447   1   3   1   0   3785    3183    2010-05-06 17:52:00 2010-05-06 17:52:00 
16447   1   3   1   0   3785    4033    2010-05-06 17:52:00 2010-05-10 16:32:00 
16447   1   3   1   0   4137    3183    2010-05-20 17:08:00 2010-05-06 17:52:00 
16447   1   3   1   0   4137    4033    2010-05-20 17:08:00 2010-05-10 16:32:00

虽然我实际上只期待最后一排。我哪里错了?

如你所见,我无法使用MAX()来检索最高记录,因为我需要通过JOIN查找另一个属性,并且我被迫使用NOT EXIST

1 个答案:

答案 0 :(得分:3)

试试这个谓词

 WHERE EXISTS (SELECT 1 
               FROM dbo.newinvoiceitem tempInvoiceItem1 
                 INNER JOIN dbo.newinvoice AS tempInvoice1 
                   ON tempInvoice1.invoice_id = tempInvoiceItem1.invoice_id 
               WHERE tempInvoiceItem1.collection_id = ssb.collection_id 
                 AND ssb.side_ordering = tempInvoiceItem1.side_ordering 
                 AND s.strat_id = tempInvoiceItem1.strat_id 
               HAVING MAX(tempInvoice1.printeddate) = Invoice1.printeddate
                 OR Invoice1.printeddate IS NULL
               )                          
       AND EXISTS (SELECT 1 
                   FROM dbo.newinvoiceitem tempInvoiceItem2 
                     INNER JOIN dbo.newinvoice AS tempInvoice2 
                       ON tempInvoice2.invoice_id = tempInvoiceItem2.invoice_id 
                   WHERE tempInvoiceItem2.collection_id = ssb2.collection_id 
                     AND ssb2.side_ordering = tempInvoiceItem2.side_ordering 
                     AND s.strat_id = tempInvoiceItem2.strat_id 
                   HAVING MAX(tempInvoice2.printeddate) = Invoice2.printeddate
                     OR Invoice2.printeddate IS NULL
                   ) 
       AND c.collection_id = 16447 

OR

 WHERE EXISTS (SELECT 1 
               FROM dbo.newinvoiceitem tempInvoiceItem1 
                 INNER JOIN dbo.newinvoice AS tempInvoice1 
                   ON tempInvoice1.invoice_id = tempInvoiceItem1.invoice_id 
               WHERE tempInvoiceItem1.collection_id = ssb.collection_id 
                 AND ssb.side_ordering = tempInvoiceItem1.side_ordering 
                 AND s.strat_id = tempInvoiceItem1.strat_id 
               HAVING MAX(tempInvoice1.printeddate) = Invoice1.printeddate                     
               )                          
       AND EXISTS (SELECT 1 
                   FROM dbo.newinvoiceitem tempInvoiceItem2 
                     INNER JOIN dbo.newinvoice AS tempInvoice2 
                       ON tempInvoice2.invoice_id = tempInvoiceItem2.invoice_id 
                   WHERE tempInvoiceItem2.collection_id = ssb2.collection_id 
                     AND ssb2.side_ordering = tempInvoiceItem2.side_ordering 
                     AND s.strat_id = tempInvoiceItem2.strat_id 
                   HAVING MAX(tempInvoice2.printeddate) = Invoice2.printeddate
                   ) 
       AND c.collection_id = 16447 OR Invoice1.printeddate IS NULL
         OR Invoice2.printeddate IS NULL