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

3phpmpom  于 2023-10-15  发布在  其他
关注(0)|答案(1)|浏览(99)

I have stored procedure I need to update for our marketing client.

I have two table variables that get filled no issue.

Currently I have a WHILE loop (see below) that processes the @SalesTable content into the 3rd table variable @SalesAndAdsTable with no issue.

The issue now is trying to insert data from the 2nd table variable @AdsTable every X iterations of the outer loop.

My idea was to try and find out what the offset was between the two tables row wise and use that number as an indicator to insert the @AdsTable record into the @SalesAndAdsTable.

Is that a sound idea or is there another method?

Code snippet after both the @SalesTable and @AdsTable getting filled below:

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

Currently, all of the required records are getting inserted into the @SalesAndAdsTable but the first two ad records get inserted it seems at the same time.

Thanks for any suggestions

3j86kqsm

3j86kqsm1#

Without seeing some sample data and expected outcome I'm not sure exactly what you are trying to achieve but it appears that you want to evenly distributed the Ads records within the Sales records??

If the date added is the principle sort then just change that in the final ORDER BY, in which case you probably don't need any of the offset code (but again, I'm guessing.

If this does not help, show some sample data and expected outcome.

If that's right then this should do the trick

-- 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

The first section is just setting up some sample data. I've included the words 'Sale' or 'Ad' in each table so that the results are easier to read.

The seconds section is just two statements, the first gets the offset and the second one just does a union of two queries.

If this is working over a large table this should be much faster than a loop (which are generally a bad idea).

Here is the result.

相关问题