1

我已经有一段时间没有在 T-SQL 环境中工作了。我之前在 Google 工作过,当然,他们有自己独特的 SQL 风格。现在我回来了,我正在阅读我的 T-SQL 功能。

我理解 MERGE 语句(至少,我想我知道!),但我正在查看示例,我看到其中包含一些我不熟悉的语法:

来自 MSDocs:

CREATE PROCEDURE Production.usp_UpdateInventory  
    @OrderDate datetime  
AS  
MERGE Production.ProductInventory AS target  
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod  
    JOIN Sales.SalesOrderHeader AS soh  
    ON sod.SalesOrderID = soh.SalesOrderID  
    AND soh.OrderDate = @OrderDate  
    GROUP BY ProductID) AS source (ProductID, OrderQty)  
ON (target.ProductID = source.ProductID)  
WHEN MATCHED AND target.Quantity - source.OrderQty <= 0  
    THEN DELETE  
WHEN MATCHED
    THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty,
                    target.ModifiedDate = GETDATE()  
OUTPUT $action, Inserted.ProductID, Inserted.Quantity,
    Inserted.ModifiedDate, Deleted.ProductID,  
    Deleted.Quantity, Deleted.ModifiedDate;  
GO  
  
EXECUTE Production.usp_UpdateInventory '20030501'  

我对以下行最感兴趣: GROUP BY ProductID) AS source (ProductID, OrderQty)

第二个括号中发生了什么?对我来说,它看起来像是列别名,但它似乎在我期望它可以工作的上下文中不起作用(SQL Server 2019)。

4

1 回答 1

2

我也从未这样做过,只是尝试假设这只是为USING子句及其列提供别名,在评估MATCHEDNOT MATCHED条件时将进一步使用这些别名。

假设你有,

MERGE Production.ProductInventory AS target  
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod  
         JOIN Sales.SalesOrderHeader AS soh  
           ON sod.SalesOrderID = soh.SalesOrderID  
          AND soh.OrderDate = @OrderDate  
       GROUP BY ProductID) AS source (ProductID, OrderQty)
........
........

source是子句的别名,是USING子句的选择语句中提到ProductID的列的别名,同样是列的别名。ProductIDUSINGOrderQtySUM(OrderQty)

这也可以写成

MERGE Production.ProductInventory AS target  
    USING (SELECT ProductID as ProductID, SUM(OrderQty) as OrderQty 
             FROM Sales.SalesOrderDetail AS sod  
             JOIN Sales.SalesOrderHeader AS soh  
               ON sod.SalesOrderID = soh.SalesOrderID  
              AND soh.OrderDate = @OrderDate  
           GROUP BY ProductID) AS source
    ........
    ........

根据我的观察,如果我们在最后给出别名,就像你的情况一样AS source (ProductID, OrderQty),其中存在的列( )被依次分配给 select 子句中提到的列的别名。

不为任何使用某种函数的列提供别名也会导致错误。

我玩过db<>fiddle,你也可以看看。

PS 这种语法我们也与 CTE 一起使用,您可能也遇到过

于 2020-09-24T17:08:45.020 回答