基于具有一对多关系的另一个更新表。没有游标

时间:2013-09-26 18:05:33

标签: sql sql-server sql-server-2008 sql-update

Table Example

我有这两个表和SQL Server中的一些示例数据。

Rules表只是SELECT DISTINCT (DataSource_Id, LocationCode, WarehouseCode, WarehouseName, MTO_Regional)表的Inventory

我想根据SS_Value中的Rules值更新MTO_MTS表格中的Inventory列,其中/如果三个中的任何一个值中有值,则SSIn ......'列。

示例:规则表中的第一条记录将根据(DataSource_Id,LocationCode,WarehouseCode,WarehouseName,MTO_MTSRegional)获取Inventory表中匹配的第一个MTO_MTS值并且具有一个'SSIn ......'不是0的列。

因此,它可以获取Inventory中前两个记录中的任何一个,因为这5个列匹配,并且至少有一个SSIn ..列是非零的

到目前为止我尝试了什么:

我尝试过使用游标但是有数百万条记录因此无法处理。我正在尝试构造一个更新语句,但无法弄清楚语法。

UPDATE Rules r
SET SS_Value = (SELECT TOP(1) MTO_MTS FROM Inventory ip
                WHERE r.DataSource_Id = ip.DataSource_Id
                AND r.LocationCode = ip.LocationCode 
                AND r.WarehouseCode = ip.WarehouseCode
                AND r.WarehouseName = ip.WarehouseName
                AND r.MTO_MTSRegional = ip.MTO_MTSRegional 
                (ip.SafetyStockInKLG <> 0 OR ip.SafetyStockInLTR <> 0 OR ip.SafetyStockInUnits <> 0)

我认为这个一般性想法可能有用,但我无法正确理解语法。

我也尝试过这样的语法:

UPDATE Rules
SET ip.SS_Value
FROM InventoryProduction ip 
INNER JOIN Rules

我遇到了查询中表格范围的问题,并从正在更新的行中获取值以应用于WHERE子句。

2 个答案:

答案 0 :(得分:0)

“第一个MTO_MTS值”是什么意思?

这将是一种方式,写为SELECT,假设“first”表示“最小”。使用它来验证它是否给出了你想要的东西,然后变成更新:

SELECT
 Rules.DataSourceID,
 Rules.LocationCode,
 Rules.WarehouseCode,
 Rules.WarehouseName,
 Rules.MTO_MTSRegional,
 SS_Value = MIN(Inventory.MTO_MTS)
FROM Rules
INNER JOIN Inventory
 ON Rules.DataSource_Id = Inventory.DataSource_Id
  AND Rules.LocationCode = Inventory.LocationCode 
  AND Rules.WarehouseCode = Inventory.WarehouseCode
  AND Rules.WarehouseName = Inventory.WarehouseName
  AND Rules.MTO_MTSRegional = Inventory.MTO_MTSRegional 
  (Inventory.SafetyStockInKLG <> 0 OR Inventory.SafetyStockInLTR <> 0 OR Inventory.SafetyStockInUnits <> 0)
GROUP BY
 Rules.DataSourceID,
 Rules.LocationCode,
 Rules.WarehouseCode,
 Rules.WarehouseName,
 Rules.MTO_MTSRegional

答案 1 :(得分:0)

第一步只选择一行可用于更新。您可以在ROW_NUMBER()的ORDER BY中添加更多列。它改变了cl输出。我希望它有效。

with cl
as
(SELECT MTO_MTS, ip.DataSource_Id, ip.LocationCode, ip.WarehouseCode, ip.WarehouseName,  ip.MTO_MTSRegional, ROW_NUMBER() OVER(PARTITION BY MTO_MTS ORDER BY DataSource_Id) rn
FROM Inventory ip inner join Rules r on
r.DataSource_Id = ip.DataSource_Id
AND r.LocationCode = ip.LocationCode 
AND r.WarehouseCode = ip.WarehouseCode
AND r.WarehouseName = ip.WarehouseName
AND r.MTO_MTSRegional = ip.MTO_MTSRegional 
where  (ip.SafetyStockInKLG <> 0 OR ip.SafetyStockInLTR <> 0 OR ip.SafetyStockInUnits <> 0)
)

UPDATE r
SET SS_Value = cl.MTO_MTS
from Rules r inner join cl on r.DataSource_Id = cl.DataSource_Id
AND r.LocationCode = cl.LocationCode 
AND r.WarehouseCode = cl.WarehouseCode
AND r.WarehouseName = cl.WarehouseName
AND r.MTO_MTSRegional = cl.MTO_MTSRegional 
where cl.rn = 1
相关问题