使用查询

时间:2018-03-12 04:50:52

标签: sql sql-server sql-server-2017

假设我预订了6小时和3个折扣,每个2小时。我想将我的预订分成3个部分,这样我就可以为每个折扣分配2个小时。

它会返回这样的内容:

BookingId 1 | DiscountId 1 | Qty 2
BookingId 1 | DiscountId 2 | Qty 2
BookingId 1 | DiscountId 3 | Qty 2

然后我会将这些记录插入到另一个表中。

我正在使用经过大量优化的查询来确定每个折扣的可用小时数。但是,我找不到一种“好”的方式来在不使用光标的情况下将预订分配给每个折扣。

(...)

WHILE @@FETCH_STATUS = 0 
BEGIN
    IF @RequiredQty = 0 
       RETURN

    IF @RequiredQty <= @AvailableQty  
    BEGIN
        INSERT INTO discount.Usage (DiscountId, BookingId, Quantity) 
        VALUES (@DiscountId, @BookingId, @RequiredQty)

        SET @RequiredQty = 0
    END

    IF @RequiredQty > @AvailableQty  
    BEGIN
        INSERT INTO discount.Usage (DiscountId, BookingId, Quantity) 
        VALUES (@DiscountId, @BookingId, @AvailableQty)

        SET @RequiredQty -= @AvailableQty
    END

    FETCH NEXT FROM ecursor INTO @DiscountId, @AvailableQty
END

DEALLOCATE ecursor

我尝试构建相应的查询,但我无法同时选择和分配变量。使用游标并不是一个真正的问题(除了一些潜在的性能问题),但我很想知道使用最新的SQL Server我们是否可以将旧游标转换为更好的游标?

谢谢, SEB

2 个答案:

答案 0 :(得分:0)

您可以使用microsoft制作表格。

像这样。

CTE RECURSIVE

enter image description here

SQLDEMO

答案 1 :(得分:0)

这是另一种方法,但不知道此代码是否具有比光标更好的性能。

DECLARE @DiscountStocks TABLE (Id INT IDENTITY(1,1), DiscountId INT, LastQty INT)
INSERT INTO @DiscountStocks (DiscountId, LastQty) VALUES (1, 5)
INSERT INTO @DiscountStocks (DiscountId, LastQty) VALUES (2, 2)
INSERT INTO @DiscountStocks (DiscountId, LastQty) VALUES (3, 1)

DECLARE @DiscountBookings TABLE (Id INT IDENTITY(1,1), DiscountId INT, BookingId INT, Qty INT)

DECLARE @BookingDiscount TABLE (Id INT IDENTITY(1,1), BookingId INT, DiscountId INT, Qty INT)
INSERT INTO @BookingDiscount (BookingId, DiscountId, Qty) VALUES (1, 1, 4)
INSERT INTO @BookingDiscount (BookingId, DiscountId, Qty) VALUES (1, 2, 2)
INSERT INTO @BookingDiscount (BookingId, DiscountId, Qty) VALUES (1, 3, 1)
INSERT INTO @BookingDiscount (BookingId, DiscountId, Qty) VALUES (2, 1, 1)
INSERT INTO @BookingDiscount (BookingId, DiscountId, Qty) VALUES (2, 2, 2)

SELECT BD.Id AS BDId, DS.Id AS DSId, DS.LastQty, BD.Qty
, DS.LastQty - (SELECT SUM(Qty) FROM @BookingDiscount WHERE Id <= BD.Id AND DiscountId = BD.DiscountId) AS QtyAfterSubstract
INTO #LastDiscountStock
FROM @DiscountStocks DS
INNER JOIN @BookingDiscount BD ON DS.DiscountId = BD.DiscountId
ORDER BY BD.Id, DS.Id

INSERT INTO @DiscountBookings (DiscountId, BookingId, Qty)
SELECT DSId, BDId, Qty
FROM #LastDiscountStock
WHERE QtyAfterSubstract >= 0

DROP TABLE #LastDiscountStock

SELECT * FROM @DiscountBookings