解释SQL连接语句

时间:2018-07-10 17:49:53

标签: mysql sql sql-server join

我应该将此查询从MYSQL转换为SQL Server。但是,join语句使我失望。我还没有看到像这样的联接完成,并且我对如何翻译它有些困惑。

SELECT 
   `Supplier Confirmed Orders` + `Log Tech Confirmed Orders`  AS 'orders confirmed',
   `Orders in CVN`-`Cancelled Orders` AS 'Orders in CVN', 
    tblloadingmonths.`month`, 
    tblvendorindex.`vendorindexid`, 
    'Service' AS category
FROM 
    tblloadingmonths 
JOIN 
    tblvendorindex 
LEFT JOIN 
    tblcvn ON tblloadingmonths.`month` = tblcvn.`month` 
    AND tblvendorindex.vendorindexid = tblcvn.vendorindexid

让我烦恼的是,loadingmonths和vendorindex表没有任何公共字段,但是它们被联接在一起,然后与cvn保持联接。我一直被教导要做tableA联接tableB ON colA = colB联接tableC ON colB = colC,但不是tableA联接talbeB左联接tableC ON colA = colC AND colB = colC。就目前而言,查询无法以联接的方式在SQL Server中运行。我必须像这样设置它:

SELECT 
    CVN.[Supplier Confirmed Orders] + CVN.[Log Tech Confirmed Orders] AS 'orders confirmed', 
    (CVN.[Orders in CVN] - CVN.[Cancelled Orders]) AS 'Orders in CVN', 
    tblloadingmonths.month, 
    tblvendorindex.vendorindexid, 
    'Service' AS category, 
    'CVN Compliance' as metric
FROM 
    cvn 
JOIN 
    tblvendorindex ON tblvendorindex.vendorindexid = CVN.vendorindexid 
INNER JOIN 
    tblloadingmonths ON tblloadingmonths.month = CVN.month

此转换后的查询获得不同的结果。任何指导将不胜感激

1 个答案:

答案 0 :(得分:0)

您被正确地教会了您应该列出连接子句(ON...),并且第二个查询显然更具可读性,因此更可取。同样,旧式联接只是在WHERE的{​​{1}}子句中列出所有内容,但同样,这很难看懂。关于您的不同结果。它们不同是因为

  1. INNER JOIN表名与cvn不同,这意味着它是一个不同的对象。如果那是O型的话...
  2. 在第一个tblcvn表到LEFT JOINingtblloadingmonths表中……表示tblloadingmonths的行中必须存在这两个行(对于您的join子句)要返回的行。但是,由于它是tblcvn,因此无论LEFT JOIN中的匹配项如何,都将返回tblloadingmonthstblloadingmonths的行。在第二个中,您将tblcvn用作基表,并始终使用cvn。这意味着要返回INNER JOIN中的行的join子句必须存在匹配项。否则,它们将被过滤。

回顾一下,使用cvn ...

  1. LEFT JOIN子句中的表很重要。用FROM表交换它可以更改结果(如您所见)
  2. LEFT JOIN子句中的条件可能会将WHERE变成LEFT联接。

我无法告诉您MySQL是否根据键分配自动分配联接,或者它是否在制造笛卡尔积。在SQL Server中使用INNER时,必须列出JOIN子句。您可以使用旧样式的连接... ON,但是这应该使您成为笛卡尔式的而没有FROM Table1, Table2...子句。这样可以使您更轻松地进行一些修改:

WHERE

感谢您的评论,您确认了MySQL联接隐式地产生了笛卡尔积,您可以在回答中用SELECT CVN.[Supplier Confirmed Orders] + CVN.[Log Tech Confirmed Orders] AS 'orders confirmed', (CVN.[Orders in CVN] - CVN.[Cancelled Orders]) AS 'Orders in CVN', tblloadingmonths.month, tblvendorindex.vendorindexid, 'Service' AS category, 'CVN Compliance' as metric FROM tblvendorindex INNER JOIN tblloadingmonths ON tblvendorindex.??? = tblloadingmonths.???? --find out what the relation is, a foreign key perpahs. Would need a data model to determine. LEFT JOIN cvn ON tblloadingmonths.month = cnv.month AND tblvendorindex.vendorindexid = cvn.vendorindexid 在SQL Server中显式实现。

CROSS JOIN