Bra*_*ore -5 sql left-join sql-server-2008 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
Run Code Online (Sandbox Code Playgroud)
编辑:虽然我想知道第一个问题的答案,但我更感兴趣的是只需要一个不需要括号的第一个FROM子句的更简单版本,所以如果你只是重写它而不是比较两者然后随意做到这一点.
ype*_*eᵀᴹ 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
Run Code Online (Sandbox Code Playgroud)
没有括号和白色空格格式:
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
Run Code Online (Sandbox Code Playgroud)
要回答另一个问题,关于第二个查询,不是它不等同.您错过了表别名并将内部联接更改为左联接.这相当于第1次:
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
Run Code Online (Sandbox Code Playgroud)
我鼓励你先写下你from的所有条款,left join然后是inner joins.这极大地简化了试图找出正在执行的查询的过程.一系列的left joins说"保留第一个表中的所有行".一系列inner joins说"只保留表格之间存在匹配的行".(有时,您可能需要第一个示例中的子查询.)
在这个例子中,两者是不一样的.在第一个中,它full join是"最外层"的连接.在第二个中,full join嵌入了一系列连接.这些从第一个到最后一个顺序解释.其中一个可能是转换full join为inner join或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
Run Code Online (Sandbox Code Playgroud)
(假设在将full join其转换为left join反正之后的某些东西).