连接操作的顺序:这两个FROM子句会产生相同的结果吗?

时间:2013-05-23 20:05:19

标签: sql sql-server-2008 left-join right-join

这两个FROM子句会产生相同的结果吗?如果没有,有没有办法写第一个,所以不需要括号?

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
编辑:虽然我想知道第一个问题的答案,但我更感兴趣的是只需要一个不需要括号的第一个FROM子句的更直接的版本,所以如果你只是想重写它比比较两个然后随意做到这一点。

2 个答案:

答案 0 :(得分:14)

我不知道第一个是否等同于第二个(第一个因为查询是不友好的格式化,说至少和第二个,因为RIGHT连接有点令人困惑,因为很多人习惯用{编写{ {1}}加入。)但回答这个问题:

  

有没有办法写第一个,所以不需要括号?

是的,您只需从第一个查询中删除括号即可。

保留括号并用一些空格格式化:

LEFT

没有括号和格式为空格:

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

答案 1 :(得分:6)

我建议您先编入fromleft join,然后再放inner join个来编写left join条款。这极大地简化了试图找出正在执行的查询的过程。一系列inner joins s表示“将所有行保留在第一个表中”。一系列full join表示“只保留表格之间存在匹配的行”。 (有时,您可能需要第一个示例中的子查询。)

在这个例子中,两者是不一样的。在第一个中,full join是“最外层”连接。在第二个中,full join嵌入在一系列连接中。这些从第一个到最后一个顺序解释。其中一个可能是将inner join转换为left joinFROM CUSMER LEFT JOIN CUSTMS ON TMS_CODE = CUS_TERM LEFT 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 。当然,如果所有表都匹配,则两者可以产生相同的结果。

第二个例子可能写成:

full join

(假设left join之后的某些内容正在将其转换为{{1}}。