T-sql多重连接

时间:2016-08-31 16:05:27

标签: sql-server tsql

INSERT INTO [dbo].[TestFactSales]
( [SalesOrderID]
, [SalesOrderDetailID]
, [OrderDateKey] -- Surrogate Key
, [ShipDateKey] -- Surrogate Key
, [CustomerKey] -- Surrogate Key
, [ProductKey] -- Surrogate Key
, [OrderQty]
, [UnitPrice]
, [UnitPriceDiscount]
) 
SELECT 
  T2.SalesOrderID
, T1.SalesOrderDetailID
--, T2.OrderDate
, T6.CalendarDateKey
--, T2.ShipDate
, T5.CalendarDateKey
--, T2.CustomerID
, T4.CustomerKey
--, T1.ProductID
, T3.ProductKey
, T1.OrderQty
, T1.UnitPrice
, T1.UnitPriceDiscount
FROM  [AdventureWorksLT2012].SalesLT.SalesOrderDetail as T1

JOIN [AdventureWorksLT2012].SalesLT.SalesOrderHeader as T2
  ON T1.SalesOrderID = T2.SalesOrderID

JOIN Tempdb.dbo.TestDimProducts as T3
 ON T1.ProductID = T3.ProductID

JOIN TempDB.dbo.TestDimCustomers as T4
 ON T2.CustomerID = T4.CustomerID

JOIN TempDB.dbo.TestDimDates as T5
 ON Cast(T2.ShipDate as date) = Cast(T5.CalendarDate as date)

JOIN TempDB.dbo.TestDimDates as T6
 ON Cast(T2.OrderDate as date) = Cast(T6.CalendarDate as date)

;
go

您好, 我有一个关于低估上面代码的问题。这是用于数据仓库实现中非常常见的连接操作的t-sql语句。我的问题是,当我们连接两个表时:

FROM  [AdventureWorksLT2012].SalesLT.SalesOrderDetail as T1
JOIN [AdventureWorksLT2012].SalesLT.SalesOrderHeader as T2
 ON T1.SalesOrderID = T2.SalesOrderID

是否意味着在T2上连接表T1和T2?在select语句中,我们有

Select
T2.SalesOrderID
, T1.SalesOrderDetailID

因此,这个选择如何理解要查看哪个表,T1或T2? 你能否澄清一下这个问题?请注意,我理解别名表示。我不明白的是插入部分。要插入[SalesOrderID],我们需要查看来自T1和T2的连接表。但代码看起来是T2.SalesOrderID。

4 个答案:

答案 0 :(得分:1)

联合表是两个表中所有列的组合 - 它不会创建一个新表,它只是来自两个表的样本。例如:

  • 表1由2列ID和名称
  • 组成
  • 表2由2列ID和描述
  • 组成
  • 将它们连接在一起现在可以使用Table1.ID,Table1.name,Table2.ID,Table2.description
  • 工作4列
  • Table1中的每一行都可以出现在Table2
  • 的每一行旁边的连接中
  • 已过滤联接表以仅显示ON子句中指定的行 - 因此在您的情况下,T1.SalesOrderID = T2.SalesOrderID
  • 的行

您使用了insert into (columns) select ... from joined table语句。

  • 您的表格中包含T1和T2的所有列。
  • 在此语句的选择部分中,您可以指定在插入TestFactSales时要使用的列。
  • 这两个表都有一个名为SalesOrderID的列,所以如果你只是把它放在那里,SQL就不知道要从哪个表中取出那个列。
  • 请记住,此联接表包含T1和T2中的所有列,因此它包含列T1.SalesOrderID和T2.SalesOrderID
  • 在您的联接中,您在ON子句中指定了T1.SalesOrderID = T2.SalesOrderID。这意味着它们对于连接表中的所有内容都是相同的。
  • 在这种特殊情况下,SalesOrderID是来自T1还是T2并不重要,因为它们的定义是相同的。

但是:

  • 情况并非总是如此,SQL Server无法知道。
  • 有时表会有相同的列名,但会加入不同的列。
  • 所以只要求T1.mycolumn可以给T2.mycolumn一个不同的答案。
  • 这就是您需要指定列来自哪个原始表的原因。

答案 1 :(得分:0)

  

是否意味着在T2上连接表T1和T2?

它正在加入表SalesOrderDetailSalesOrderHeader,并将它们别名为T1T2

  

因此,这个选择如何理解要查看哪个表,T1或T2?

它在查询中明确指定:

SELECT 
  T2.SalesOrderID
, T1.SalesOrderDetailID

因此,查询正在查找表SalesOrderID中的T2SalesOrderHeader的别名),并在表SalesOrderDetailID中查找T1 }(这是SalesOrderDetail的别名)。

这个(带表别名):

SELECT 
  T2.SalesOrderID,
  T1.SalesOrderDetailID
FROM SalesOrderDetail AS T1
  JOIN SalesOrderHeader AS T2
  ON T1.SalesOrderID = T2.SalesOrderID

与此相同(没有表别名):

SELECT
  SalesOrderHeader.SalesOrderID,
  SalesOrderDetail.SalesOrderDetailID
FROM SalesOrderDetail
  JOIN SalesOrderHeader
  ON SalesOrderDetail.SalesOrderID = SalesOrderHeader.SalesOrderID

在查询中使用表别名只会缩短整个查询中所有长表名称的重复。 (虽然使用T1T2这样的别名似乎模糊了有关这些表的有用信息,但是这个代码可能是由一个无法使用有意义的别名的工具自动生成的的名称。)

答案 2 :(得分:0)

以下代码使用T1T2作为别名。 AS子句创建表别名。因此,[AdventureWorksLT2012].SalesLT.SalesOrderDetail现在可以被引用为T1

 FROM  [AdventureWorksLT2012].SalesLT.SalesOrderDetail as T1 JOIN
 [AdventureWorksLT2012].SalesLT.SalesOrderHeader as T2  ON
 T1.SalesOrderID = T2.SalesOrderID

在select语句中,T1等同于[AdventureWorksLT2012].SalesLT.SalesOrderDetail,当您键入ALIAS.Column_Name时,sql将足够智能查找别名并搜索正确的表

 Select
 T2.SalesOrderID
 , T1.SalesOrderDetailID

MSDN on Table aliasing

答案 3 :(得分:0)

查询正在查看表[AdventureWorksLT2012].SalesLT.SalesOrderDetail[AdventureWorksLT2012].SalesLT.SalesOrderHeader。这是一对多的关系。

T1T2只是长表名称的别名。

SalesOrderHeader包含一般信息,例如SalesOrderId,customerId,orderDate。

SalesOrderDetail表包含为此特定SalesOrderId订购的商品。该表至少包含SalesOrderId,ItemId,Quantity。

加入这两张表将提供有关客户在此特定发票上购买的商品的信息。加入条件为T2.SalesOrderId = T1.SalesOrderId