0

I understand that this type of procedure is NOT preferable nor efficient, but I am at a point where this type of table is needed since I have not been able to get a response to my original question (Fill In for Null Values for Date, Product Code & QTY) on here. I found this relevant post/answer (While loop with multiple conditions in T-SQL) but need it adapted to my scenario. As I am only a data-querying guy I haven't a clue what I am doing in this while begin loop that I failed to BM where I drafted it from.

I am in the same scenario as the user in the aforementioned post, I don't want to have to create this type of table but am out of options and help. Am very much hoping I can get some help/answers as the user above did.

Help me ObiOneOverflow, you're my only hope!

I am trying to create a daily reference record for each product code between two dates, looping on the ROWID till it gets to the last ROWID integer. It is breaking somewhere, I just don't have the experience in this type of programming to figure out why nor where, I HAVE tried changing parts to see how it reacts, but never getting a successful run.

I hope you pros can simply see where I'm causing it to fail on a loop and keep iterating up between the dates, then restarting on the next ROWID from the product table.

    CREATE TABLE FACT_ECODEMONTHLY
        ( 
            STARTDT DATE NOT NULL,
            MONTHEND DATE NOT NULL,
            ECODE VARCHAR (255)
        );

    DECLARE @STARTDT DATE
    DECLARE @ENDDT DATE
    DECLARE @TEMPDT DATE
    DECLARE @START INT
    DECLARE @END INT
    DECLARE @TEMPNO INT
    DECLARE @ROWID INT
    DECLARE @ECODE VARCHAR (255)

    SET @STARTDT = '2017-01-01'
    SET @ENDDT = '2022-12-31'
    SELECT @START = MIN(DE1.ROW_ID), @END = MAX(DE1.ROW_ID) FROM DIM_ECODES DE1 
    SET @ECODE = ( SELECT DE2.ECODE FROM DIM_ECODES DE2 WHERE ROW_ID = @START )

    BEGIN

        WHILE (@STARTDT <= @ENDDT) AND (@START <= @END )
            BEGIN
                SET @TEMPDT = @STARTDT;
                SET @TEMPDT =  DATEADD( DAY , 1 , @TEMPDT)

        WHILE (@START <= @END )
            BEGIN 
                SET @TEMPNO = @START;
                SET @TEMPNO = @TEMPNO + 1

        INSERT INTO FACT_ECODEMONTHLY 
        ( STARTDT ,  MONTHEND , ECODE ) 

                VALUES 
                    ( @STARTDT , EOMONTH(@STARTDT) , @ECODE )

                    IF (@STARTDT <= @ENDDT )
                    BEGIN
                        SET @STARTDT = @TEMPDT
                    END
                    ELSE
                    BEGIN
                        SET @STARTDT = '2017-01-01'
                        SET @ENDDT = DATEADD (DAY , 1 , @STARTDT)
                    END

                    IF (@START <= @END)
                    BEGIN
                        SET @START = @TEMPNO
                    END
                    ELSE
                    BEGIN
                        SET @START = 1
                        SET @END = @START + 1
                    END

            END
            END
    END

When I run the above, I get the following:

How it processes

What it produces

Thank you for looking and any assistance provided.

Schema (MySQL v8.0)

CREATE TABLE DIM_ECODES
    (

        ECODE VARCHAR(255) NOT NULL,
        MCODE VARCHAR(255) NOT NULL,
        SOURCE VARCHAR(255) NOT NULL,
        ROW_ID INT

    );

INSERT INTO DIM_ECODES

    (ECODE , MCODE , SOURCE , ROW_ID )
    
 VALUES
 
('Q5142-80','Q5999-571','TEAM',1),
('P1DH6-','P1DH6-', 'TEAM',2),
('U616Z-051','U520U-','TEAM',3),
('14404-31','14404-31', 'TEAM',4),
('R6980-','R6980-', 'TEAM',5);

Query #1

SELECT *

FROM DIM_ECODES;
ECODE MCODE SOURCE ROW_ID
Q5142-80 Q5999-571 TEAM 1
P1DH6- P1DH6- TEAM 2
U616Z-051 U520U- TEAM 3
14404-31 14404-31 TEAM 4
R6980- R6980- TEAM 5

View on DB Fiddle


DESIRED RESULTS EXAMPLE

DATE EOM ECODE
1/1/2017 1/31/2017 Q5142-80
1/2/2017 1/31/2017 Q5142-80
1/3/2017 1/31/2017 Q5142-80
1/4/2017 1/31/2017 Q5142-80
1/5/2017 1/31/2017 Q5142-80
1/6/2017 1/31/2017 Q5142-80
1/7/2017 1/31/2017 Q5142-80
1/8/2017 1/31/2017 Q5142-80
1/9/2017 1/31/2017 Q5142-80
1/10/2017 1/31/2017 Q5142-80
1/11/2017 1/31/2017 Q5142-80
1/12/2017 1/31/2017 Q5142-80
1/13/2017 1/31/2017 Q5142-80
1/14/2017 1/31/2017 Q5142-80
1/15/2017 1/31/2017 Q5142-80
1/16/2017 1/31/2017 Q5142-80
1/17/2017 1/31/2017 Q5142-80
1/18/2017 1/31/2017 Q5142-80
1/19/2017 1/31/2017 Q5142-80
1/20/2017 1/31/2017 Q5142-80
1/21/2017 1/31/2017 Q5142-80
1/22/2017 1/31/2017 Q5142-80
1/23/2017 1/31/2017 Q5142-80
1/24/2017 1/31/2017 Q5142-80
1/25/2017 1/31/2017 Q5142-80
1/26/2017 1/31/2017 Q5142-80
1/27/2017 1/31/2017 Q5142-80
1/28/2017 1/31/2017 Q5142-80
1/29/2017 1/31/2017 Q5142-80
1/30/2017 1/31/2017 Q5142-80
1/31/2017 1/31/2017 Q5142-80
1/1/2017 1/31/2017 P1DH6-
1/2/2017 1/31/2017 P1DH6-
1/3/2017 1/31/2017 P1DH6-
1/4/2017 1/31/2017 P1DH6-
1/5/2017 1/31/2017 P1DH6-
1/6/2017 1/31/2017 P1DH6-
1/7/2017 1/31/2017 P1DH6-
1/8/2017 1/31/2017 P1DH6-
1/9/2017 1/31/2017 P1DH6-
1/10/2017 1/31/2017 P1DH6-
1/11/2017 1/31/2017 P1DH6-
1/12/2017 1/31/2017 P1DH6-
1/13/2017 1/31/2017 P1DH6-
1/14/2017 1/31/2017 P1DH6-
1/15/2017 1/31/2017 P1DH6-
1/16/2017 1/31/2017 P1DH6-
1/17/2017 1/31/2017 P1DH6-
1/18/2017 1/31/2017 P1DH6-
1/19/2017 1/31/2017 P1DH6-
1/20/2017 1/31/2017 P1DH6-
1/21/2017 1/31/2017 P1DH6-
1/22/2017 1/31/2017 P1DH6-
1/23/2017 1/31/2017 P1DH6-
1/24/2017 1/31/2017 P1DH6-
1/25/2017 1/31/2017 P1DH6-
1/26/2017 1/31/2017 P1DH6-
1/27/2017 1/31/2017 P1DH6-
1/28/2017 1/31/2017 P1DH6-
1/29/2017 1/31/2017 P1DH6-
1/30/2017 1/31/2017 P1DH6-
1/31/2017 1/31/2017 P1DH6-
4
  • In regards to why you might not have got a response, there's a lot of data in that other question, but none of the sample data is in DDL and DML statements; that can be a "turn off" for many users whom then have to take your text and translate it into DML statements, and create DDL statements for tables to put said data into. Commented May 5, 2021 at 15:44
  • Hey @Larnu, thanks for that bit of info. I'll look into how to do that, the person who was commenting with a 1.1M rep points suggested I add it as text tables. Any chance you see why/where my loop is failing on this question? Commented May 5, 2021 at 15:52
  • You don't need to do any looping for this, include actual sample data and desired results and someone can easily product a far more efficient set-based solution. Commented May 5, 2021 at 16:42
  • Added, @Stu. Hopefully that'll helps provide an answer. Commented May 5, 2021 at 17:39

1 Answer 1

0

You are getting all the same values because you initialize the temp variables at each loop with the same start value. You must initialize them before the loops and increment them in the loops, at the end of the loops

SET @TEMPDT = @STARTDT;
WHILE (@TEMPDT <= @ENDDT)
BEGIN
    SET @TEMPNO = @START;
    WHILE (@TEMPNO  <= @END )
    BEGIN 

        -- execute your query here --

        SET @TEMPNO = @TEMPNO + 1;
    END
    SET @TEMPDT =  DATEADD( DAY , 1 , @TEMPDT)
END

It helps a lot if you indent the code to make the structure visible. In my code you see immediately that it contains two nested loops and what is before, in and after the loops.

You don't need to combine two conditions in the first loop. Each loop is responsible to check the upper limit of its own loop variable. It is also wrong to test @STARTDT and @START in the conditions, since you are incrementing @TEMPDT and @TEMP.

Before the first loop you set the initial value of @TEMPDT. The WHILE loop tests whether it is not exceeding @ENDDT and at the end increments it.

The second, nested loop does the same for @TEMPNO. This also means that for each date, @TEMPNO will go from @START to @END.


Update related to your comment. If you don't want each day being repeated, I'm not sure why you have created nested loops. If the intention was to repeat the ECODEs, then I would directly insert them from the DIM_ECODES table

SET @TEMPDT = @STARTDT;
WHILE (@TEMPDT <= @ENDDT)
BEGIN

    INSERT INTO FACT_ECODEMONTHLY (STARTDT, MONTHEND, ECODE)
    SELECT @TEMPDT, EOMONTH(@TEMPDT), ECODE
    FROM DIM_ECODES
    WHERE ROW_ID BETWEEN @START AND @END;
 
    SET @TEMPDT =  DATEADD( DAY , 1 , @TEMPDT)
END

It is always faster to execute SQL commands than loops when accessing databases.

This does not insert in the same order as in your example, but records in a table do, by definition, not have a defined order. If you need a specific order you must specify it when querying the data anyway.

SELECT *
FROM FACT_ECODEMONTHLY 
ORDER BY STARTDT, ECODE;

If you need the same order as given by DIM_ECODES.ROW_ID, then you must add such a column to the FACT_ECODEMONTHLY table as well.

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thank you this has gotten me closer to the goal but I think I am still missing something. When I run a test for a single month and row_id I do get the intended results (prntscr.com/12j69jz) but when I set the @End to 2 for a secondary test I get the following results: prntscr.com/12j6ewd

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.