Search code examples
sqlsql-server-2008left-joinright-join

Order of join operations: would these two FROM clauses produce the same results?


Would these two FROM clauses produce the same results? And if not, is there a way to write the the first one so that no parenthesis are needed?

FROM            SALESTAX
     RIGHT JOIN (            ITEMS
                  RIGHT JOIN (            PINVOICE
                               INNER JOIN PINVDET ON PINVOICE.PNV_INVOICENO = PINVDET.PND_INVOICENO AND PINVOICE.PNV_Site = PINVDET.PND_Site
                             ) ON ITEMS.ITE_INVNO = PINVDET.PND_INVNO
                ) ON SALESTAX.STX_GroupID = PINVDET.PND_TAX1
      FULL JOIN (            CUSTMS
                  RIGHT JOIN CUSMER ON CUSTMS.TMS_CODE = CUSMER.CUS_TERM
                ) ON PINVDET.PND_CUSTID = CUSMER.CUS_CustID

FROM  CUSTMS RIGHT JOIN
      CUSMER ON TMS_CODE = CUS_TERM FULL JOIN
      PINVDET ON PND_CUSTID = CUS_CustID LEFT JOIN
      PINVOICE ON PNV_INVOICENO = PND_INVOICENO AND PNV_Site = PND_Site LEFT JOIN
      SALESTAX on STX_GROUPID = PND_TAX1 left join
      ITEMS on ITE_INVNO = PND_INVNO

EDIT: While I'd like to know the answer to the first question, I'm more immediately interested in just having a more straightforward version of the first FROM clause that doesn't need parenthesis so if you'd rather just rewrite it than compare the two then feel free to just do that.


Solution

  • I have no idea if the 1st is equivalent to the 2nd (first because the queries are unfriendly formatted, to say the least and second because RIGHT joins are kind of confusing, since many are used to write using LEFT joins.) But to answer the question:

    Is there a way to write the the first one so that no parenthesis are needed?

    Yes, you can simply remove the parentheses from the 1st query.

    Keeping the parentheses and formatted with some white space:

    FROM 
            SALESTAX
        RIGHT JOIN 
            (   ITEMS
            RIGHT JOIN 
                (   PINVOICE
                INNER JOIN 
                    PINVDET 
                  ON  PINVOICE.PNV_INVOICENO = PINVDET.PND_INVOICENO 
                  AND PINVOICE.PNV_Site = PINVDET.PND_Site
                ) 
              ON ITEMS.ITE_INVNO = PINVDET.PND_INVNO
            ) 
          ON SALESTAX.STX_GroupID = PINVDET.PND_TAX1
        FULL JOIN 
            (   CUSTMS
            RIGHT JOIN
                CUSMER 
              ON CUSTMS.TMS_CODE = CUSMER.CUS_TERM
            ) 
          ON PINVDET.PND_CUSTID = CUSMER.CUS_CustID
    

    Without parentheses and white-space formatted:

    FROM    
            SALESTAX
        RIGHT JOIN
                ITEMS
            RIGHT JOIN
                    PINVOICE
                INNER JOIN 
                    PINVDET 
                  ON  PINVOICE.PNV_INVOICENO = PINVDET.PND_INVOICENO
                  AND PINVOICE.PNV_Site = PINVDET.PND_Site
              ON ITEMS.ITE_INVNO = PINVDET.PND_INVNO
          ON SALESTAX.STX_GroupID = PINVDET.PND_TAX1
        FULL JOIN
                CUSTMS
            RIGHT JOIN 
                CUSMER 
              ON CUSTMS.TMS_CODE = CUSMER.CUS_TERM
          ON PINVDET.PND_CUSTID = CUSMER.CUS_CustID
    

    To answer the other question, about the 2nd query, no it isn't equivalent. You missed the table aliases and changed an inner join to left join. This is equivalent to the 1st:

    FROM  CUSMER  
            LEFT JOIN
          CUSTMS     ON  CUSTMS.TMS_CODE = CUSMER.CUS_TERM
       FULL JOIN
          PINVDET
            INNER JOIN                                      -- this is changed
          PINVOICE   ON  PINVOICE.PNV_INVOICENO = PINVDET.PND_INVOICENO
                     AND PINVOICE.PNV_Site = PINVDET.PND_Site
            LEFT JOIN
          ITEMS      ON  ITEMS.ITE_INVNO = PINVDET.PND_INVNO
            LEFT JOIN
          SALESTAX   ON  SALESTAX.STX_GroupID = PINVDET.PND_TAX1
       ON PINVDET.PND_CUSTID = CUSMER.CUS_CustID