Sql server 有没有办法用内部联接更新TOP(N),其中N是此类内部联接的字段?

Sql server 有没有办法用内部联接更新TOP(N),其中N是此类内部联接的字段?,sql-server,sql-update,Sql Server,Sql Update,我正在尝试创建一个同步销售和库存表的脚本。为此,我在库存表上写了一个更新,每个库存项目有一条记录,如下所示: UPDATE TOP (q.QuantitySold) i SET i.Converted = 1, i.CartID = q.CartID, i.ReservedDate = GETDATE() FROM Inventory i INNER JOIN ( SELECT product.ProductID, sales.CartID, COUNT(sales.ID

我正在尝试创建一个同步销售和库存表的脚本。为此,我在库存表上写了一个更新,每个库存项目有一条记录,如下所示:

UPDATE TOP (q.QuantitySold) i
SET i.Converted = 1,
    i.CartID = q.CartID,
    i.ReservedDate = GETDATE()
FROM Inventory i
INNER JOIN
(
    SELECT product.ProductID, sales.CartID, COUNT(sales.ID) AS QuantitySold
    FROM Products product
    INNER JOIN Sales sales ON sales.ProductID = product.ProductID
    WHERE <conditions> 
    GROUP BY product.ProductID, sales.CartID
) q ON q.ProductID = i.ProductID
WHERE i.Converted = 0 AND i.CartID IS NULL 
但它不起作用,error说q.quantitysell不能被绑定

是否有一种方法可以在不使用光标的情况下更新等于销售数量的N个存货记录?我拒绝那样放弃

注意:这是实际查询的简化版本。

您可以使用行号来枚举需要更新的库存项目

WITH cteProducts AS(
    SELECT product.ProductID, sales.CartID, COUNT(sales.ID) AS QuantitySold
    FROM Products product
    INNER JOIN Sales sales ON sales.ProductID = product.ProductID
    WHERE <conditions> 
    GROUP BY product.ProductID, sales.CartID
),
cteInventory AS(
    SELECT *,
        ROW_NUMBER() OVER( PARTITION BY ProductID ORDER BY (SELECT NULL)) AS rn /*Change the ORDER BY for an actual column if needed, probably for FIFO*/
    FROM Inventory
    WHERE i.Converted = 0 
    AND i.CartID IS NULL 
)
UPDATE i
SET i.Converted = 1,
    i.CartID = q.CartID,
    i.ReservedDate = GETDATE()
FROM cteInventory i
INNER JOIN cteProducts q ON q.ProductID = i.ProductID
WHERE i.rn <= q.QuantitySold;

您的top没有orderby,因此即使这样做有效,您也无法知道哪些行将被更新。但是是的,你可以做到这一点,只是不像你想做的那样。您不更新前x行,而是使用查询仅返回前10行。最简单的方法是使用cte获得前10名,然后更新cte。我知道,但在这种特殊情况下,我不关心更新哪些行,只要它们没有转换并且没有购物车id。当然,非确定性更新不是很好。你对CTE的看法是正确的,已经按照路易斯的建议尝试过了,并且成功了。很高兴你找到了解决方案。这是批量更新类型的一部分吗?这大概是我能看到你不在乎更新的地方的唯一原因。是的。这是库存的批量同步加上迁移。长话短说:旧系统中有一些销售没有反映在新系统中。这个旧系统将要退役,所以在关闭它之前,我们需要在新系统中有正确数量的可用库存。哈,几乎和我的一样+1实际上,我建议将I.Converted=0且I.CartID为NULL放在cteInventory的WHERE中。否则,您可能会得到Converted=1且RN值较低的行。谢谢@LuisCazares和@Larnu!它似乎在我的简单测试场景中起作用。我现在将在真实的案例中试用,看看效果如何。我很想给你的答案打分,但显然我的声誉太低了