将两个表变量数据组合到第三个表变量中,其中每个 X 行插入第二个表变量中的记录

Combing two table variables data into third table variable where the records from the 2nd table variable are inserted every X rows

提问人:Joey007 提问时间:9/24/2023 最后编辑:Dale KJoey007 更新时间:9/24/2023 访问量:42

问:

我有存储过程,我需要为我们的营销客户更新。

我有两个表格变量被填满没有问题。

目前,我有一个 WHILE 循环(见下文),可以毫无问题地将@SalesTable内容处理到第 3 个表变量@SalesAndAdsTable中。

现在的问题是尝试在外部循环的每 X 次迭代@AdsTable插入来自第二个表变量的数据。

我的想法是尝试找出两个表之间的偏移量,并使用该数字作为指示器将@AdsTable记录插入@SalesAndAdsTable。

这是一个好主意还是有其他方法?

下面填写了@SalesTable和@AdsTable后的代码片段:

SET @OffSet = (SELECT @SalesTableCnt/@AdsTableCnt);
        
        WHILE (SELECT COUNT(*) FROM @SalesTable WHERE processed = 0) > 0
        BEGIN

            SELECT TOP 1 @SaleId = saleid FROM @SalesTable WHERE processed = 0 ORDER BY dateadded DESC;

            -- check if @OffSet matches the @SaleCnt, INSERT AD Record into @SalesAndAdsTable, update @AdsTable setting processed = 1, RESET @SaleCnt to 0 

            -- INSERT this SALE record into @SalesAndAdsTable
            INSERT INTO @SalesAndAdsTable SELECT * FROM @SalesTable WHERE saleid = @SaleId;

            -- C. Finally, update the table variable, set the 'Processed' column of the processed row to 1. 
            UPDATE @SalesTable SET processed = 1 Where saleid = @SaleId;


            --AD INJECTION...
            IF @OffSet = @SaleCnt AND @OffSet >= 0
            BEGIN

                SELECT TOP 1 @AdId = saleid FROM @AdsTable WHERE processed = 0 ORDER BY dateadded DESC;;
        
                -- INSERT this AD record into @SalesAndAdsTable
                INSERT INTO @SalesAndAdsTable SELECT * FROM @AdsTable WHERE @AdId = saleid;

                UPDATE @AdsTable SET processed = 1 Where saleid = @AdId; 

                SET @SaleCnt = 0;
                SET @AdCnt = @AdCnt + 1;
                
                --SELECT @AdId as '@AdId';

            END

            -- increase this loops counter variable
            SET @SaleCnt = @SaleCnt + 1;

            --SELECT @SaleCnt as '@SaleCnt', @OffSet as '@OffSet', @SaleId as '@SaleId';

        END

目前,所有必需的记录都插入到@SalesAndAdsTable中,但前两个广告记录似乎同时插入。

感谢您的任何建议

sql sql-server while-loop

评论

0赞 Dale K 9/24/2023
你真的需要提供一个最小的可重现的例子,强调最小的,即将问题简化为最简单的形式。就目前而言,当你希望人们尝试理解大量代码时,你的期望太高了
0赞 Joey007 9/24/2023
谢谢,我调整了snipit以仅显示WHILE LOOP。
0赞 Yitzhak Khabinsky 9/24/2023
在提出问题时,您需要提供一个最小的可重现示例:(1) DDL 和样本数据填充,即 CREATE 表加上 INSERT T-SQL 语句。(2)你需要做什么,即逻辑和你的代码尝试在T-SQL中实现它。(3) 期望的输出,基于上面 #1 中的示例数据。(4) 您的 SQL Server 版本 (SELECT @@version;)。所有问题都是文本,没有图像。
1赞 Charlieface 9/24/2023
我非常怀疑这根本不需要任何循环,但如果没有样本数据和预期结果,真的很难理解。

答:

0赞 Alan Schofield 9/24/2023 #1

在没有看到一些样本数据和预期结果的情况下,我不确定您到底要实现什么,但您似乎想在销售记录中均匀分布广告记录??

如果添加的日期是原则排序,那么只需在最终的 ORDER BY 中更改它,在这种情况下,您可能不需要任何偏移代码(但同样,我猜。

如果这没有帮助,请显示一些示例数据和预期结果。

如果这是正确的,那么这应该可以解决问题

-- Set up some sample data

DECLARE @Sales TABLE (SaleID int, DateAdded date, SomeText varchar(10), SomeNumber decimal(10,2))
DECLARE @Ads TABLE (AdID int, DateAdded date, SomeText varchar(10), SomeNumber decimal(10,2))

INSERT INTO @Sales VALUES 
(50, '2023-09-15', 'Sale', 11.1), (30, '2023-09-16', 'Sale', 22.2), (35, '2023-09-17', 'Sale', 33.3), (8,  '2023-09-18', 'Sale', 44.4), 
(9,  '2023-09-19', 'Sale', 55.5), (55, '2023-09-20', 'Sale', 66.6), (99, '2023-09-21', 'Sale', 77.7), (33, '2023-09-22', 'Sale', 88.8)

INSERT INTO @Ads VALUES (1, '2023-09-15', 'Ad', 1.1), (2, '2023-09-20', 'Ad', 2.2),(3, '2023-09-21', 'Ad', 3.3)

-- The query

DECLARE @Offset Decimal(10,5) = ((SELECT CAST(COUNT(*) as decimal(10,5)) FROM @Sales) / ((SELECT CAST(COUNT(*) as decimal(10,5)) FROM @Ads)))

select *, ROW_NUMBER() OVER(ORDER BY DateAdded DESC) as rn from @Sales
UNION ALL
select *, (ROW_NUMBER() OVER(ORDER BY DateAdded DESC) * @Offset) + 0.00001 as rn from @Ads
ORDER BY rn
    

第一部分只是设置一些示例数据。我在每个表格中都包含了“销售”或“广告”这两个词,以便结果更易于阅读。

seconds 部分只是两个语句,第一个语句获取偏移量,第二个语句仅执行两个查询的并集。

如果这是在大表上工作,这应该比循环快得多(这通常是一个坏主意)。

这是结果。

enter image description here

评论

0赞 Joey007 9/24/2023
谢谢艾伦,我会试一试的。我知道我不想走光标路线,并认为也许 WHILE 循环会起作用,但是是的,好主意!谢谢你,干杯!
0赞 Alan Schofield 10/1/2023
别客气。如果这回答了您的问题,请将答案标记为已接受(投票赞成/反对按钮下方左侧的复选框)。这有助于其他用户找到类似问题的答案