Reputation: 171
When using nested LOOP or WHILE loop in bigquery, it seems I am not able to iterate again over the outer loop. The problem can be reproduced with the code below.
DECLARE i int64 DEFAULT 0;
DECLARE j int64 DEFAULT 0;
DECLARE k int64 DEFAULT 0;
WHILE i < 3 DO
SET i = i + 1;
WHILE j < 2 DO
SET j = j + 1;
IF j = 2 THEN
SET k = k+7;
END IF;
EXECUTE IMMEDIATE """
WITH test AS(SELECT @i2 AS i, @j2 AS j, @k2 AS k)
SELECT * FROM test
"""
USING i AS i2, j AS j2, k AS k2;
END WHILE;
END WHILE;
As output of this, Bigquery give me back two iterations (the inner loop):
Row | i | j | k |
---|---|---|---|
1 | 1 | 1 | 0 |
Row | i | j | k |
---|---|---|---|
1 | 1 | 2 | 7 |
I would expect that, when we end the inner while loop, we would go to the outer one and start over. Ending up in something like:
Row | i | j | k |
---|---|---|---|
1 | 2 | 2 | 7 |
What is the right way to do this? When using the same set-up but with a LOOP and BREAK condition, the results are exactly the same as explained as above. when using CONTINUE instead of BREAK my query runs forever / keeps hanging at the second statement
Upvotes: 1
Views: 664
Reputation: 172974
I would expect that, when we end the inner while loop, we would go to the outer one and start over
It actually performs exactly as you expected - to check this - run below with extra line so you will see the proof
DECLARE i int64 DEFAULT 0;
DECLARE j int64 DEFAULT 0;
DECLARE k int64 DEFAULT 0;
WHILE i < 3 DO
SET i = i + 1;
SELECT i; # insert this line to check correctness
WHILE j < 2 DO
SET j = j + 1;
IF j = 2 THEN
SET k = k+7;
END IF;
EXECUTE IMMEDIATE """
WITH test AS(SELECT @i2 AS i, @j2 AS j, @k2 AS k)
SELECT * FROM test
"""
USING i AS i2, j AS j2, k AS k2;
END WHILE;
END WHILE;
So, obviously for i = 2
- WHILE j < 2 DO
evaluated as false and thus skipped
What is the right way to do this?
It depends on what you are trying to achieve - but usually this is done by resetting j inside first loop as in below example
DECLARE i int64 DEFAULT 0;
DECLARE j int64 DEFAULT 0;
DECLARE k int64 DEFAULT 0;
WHILE i < 3 DO
SET i = i + 1;
SET j = 0; # reset j
WHILE j < 2 DO
SET j = j + 1;
IF j = 2 THEN
SET k = k+7;
END IF;
EXECUTE IMMEDIATE """
WITH test AS(SELECT @i2 AS i, @j2 AS j, @k2 AS k)
SELECT * FROM test
"""
USING i AS i2, j AS j2, k AS k2;
END WHILE;
END WHILE;
Upvotes: 2