-5

这两个 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 子句的更直接版本,所以如果你宁愿重写它而不是比较两者,然后随意这样做。

4

2 回答 2

14

我不知道第一个是否等同于第二个(首先是因为查询格式不友好,至少可以这么说,其次是因为RIGHT连接有点令人困惑,因为很多人习惯于使用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

要回答另一个问题,关于第二个查询,不,它不等效。您错过了表别名并将内部联接更改为左联接。这相当于第一个:

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
于 2013-05-23T20:18:53.147 回答
6

我鼓励您通过将所有s 放在首位,然后是s 来编写您的from从句。这极大地简化了试图找出查询在做什么的过程。一系列s 表示“保留第一个表中的所有行”。一系列说“只保留表之间匹配的行”。(有时,您可能需要像第一个示例中那样的子查询。)left joininner joinleft joininner joins

在此示例中,两者不太可能相同。首先,full join是“最外层”的连接。在第二个中,full join嵌入在一系列连接中。这些是从第一个到最后一个顺序解释的。其中之一可能是将 转换full joininner joinor left join。当然,如果所有表都匹配,则两者可以产生相同的结果。

第二个例子大概可以写成:

FROM  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正在将其转换为a left join)。

于 2013-05-23T20:19:07.240 回答