Google Cloud BigQuery - sql

I have a set of data (x, y) where x = 1 to 5 , y = 1 to 10
e.g. extract from them one by one where (1,1),(1,2),(1,3)…(1,10)…(2,5)…(5,10)
BEGIN
DECLARE
x,y INT64 DEFAULT 0;
LOOP
SET
x = x + 1;
IF
x <= Max(x) THEN
LOOP
SET
y = y + 1;
IF
y <= Max(y) THEN
CALL
data(x,y);
ELSE
BREAK;
END IF;
END LOOP;
END IF;
END LOOP;
END
Does anyone help me ?

I think CROSS JOIN with GENERATE_ARRAY will works better for you
SELECT * FROM UNNEST(GENERATE_ARRAY(1,5)) x, UNNEST(GENERATE_ARRAY(1,10)) y
Is it?

Related

SELECT a loop over an Array type. BigQuery

Is there any way to loop over an array column within SELECT clause in Google's BigQuery?. Using pseudo-sql:
-- This is some arbitrary complex logic which can be resume as: sum some product while some accumulator is less than a value
accumulator1 = 0
accumulator2 = 0
user_defined_loop =
FOR (x, y) in array
accumulator1 += x * y
accumulator2 += y
IF accumulator2 <= 5000
CONTINUE
ELSE
BREAK
END IF
RETURN accumulator2
END;
WITH example AS (
SELECT [(1,20), (3,40), (5,60)] as array_type_column
UNION ALL
SELECT [(7,80), (9,100), (5,110)]
UNION ALL
SELECT [(5,7), (30,40), (50,60)]
)
SELECT user_defined_loop(array_type_column)
FROM example
Thanks in advance
Try JavaScrpt UDFs:
CREATE TEMP FUNCTION user_defined_loop(arr ARRAY<STRUCT<x INT64, y INT64>>)
RETURNS INT64
LANGUAGE js
AS """
var accumulator1 = 0
var accumulator2 = 0
for (const item of arr)
{
accumulator1 += parseInt(item.x) * parseInt(item.y)
accumulator2 += parseInt(item.y)
if (accumulator2 > 5000) break
}
return accumulator2;
""";
WITH example AS (
SELECT [(1,20), (3,40), (5,60)] as array_type_column
UNION ALL
SELECT [(7,80), (9,100), (5,110)]
UNION ALL
SELECT [(5,7), (30,40), (50,60)]
)
SELECT user_defined_loop(array_type_column)
FROM example

Jacobi method to a system with a tolerance

Evening all, I have had a similar issue previously with this type of code however I have not been able to figure this one out. I am trying to run my Jacobi code with an initial approximation of the 0 vector, and with tolerance Matrix norm (X^n - x^(n-1)) < 1e^-2
restart;
jacobi:=proc(A::Matrix,b::Vector,x0::Vector,m::integer)
local n,i,j,S,x::Vector,x1::Vector;
x1:=Vector(x0); x := Vector(m);
ee:= LinearAlgebra[VectorNorm](x-x1);
for n from 1 to 50 while ee < 1e-2 do
for i from 1 to m do
S:=0.0;
for j from 1 to m do
if j<>i then S:=S+A[i,j]*x1[j]; end if;
end do;
x[i]:=(-S+b[i])/A[i,i];
end do;
for j from 1 to m do
x1[j]:=x[j];
end do;
print(n,x);
end do;
return x
end proc;
A:=Matrix([[12.4,0.3,-2.2,0.2,3.6],[1.2,7.1,-1.7,-1.6,0.9],[1.3,3.1,10.8,2.2,0.7],[-1.4,0.8,1.1,-7.7,-1.8],[2.8,6.4,0.0,-1.2,-16.6]]);
b:=Vector([-3.5,19.58,-24.56,8.16,-9.28]);
x0:=Vector([0,0,0,0,0]);
jacobi(A,b,x0,5);
#Error, (in jacobi) Vector index out of range
Error, (in LinearAlgebra:-Norm) expects its 1st argument, A, to be of type {Matrix, Vector}, but received x-x1
I found a solution!
restart;
jacobi:=proc(A::Matrix,b::Vector,x0::Vector,m::integer,N::integer,tol::float)
local n,i,j,S,ee,x::Vector,x1::Vector;
x1:=Vector(x0); x := Vector(m); n:=1;
do
for i from 1 to m do
S:=0.0;
for j from 1 to i-1 do
S:=S+A[i,j]*x1[j]
end do;
for j from i+1 to m do
S:=S+A[i,j]*x1[j]
end do;
x[i]:=(-S+b[i])/A[i,i];
end do;
ee:= LinearAlgebra[VectorNorm](x-x1);
if(ee<tol) then
printf("The solution after %d iterations is:",n);
print(x);
break;
end if;
for j from 1 to m do
x1[j]:=x[j];
end do;
n:=n+1;
if (n>N) then error("No convergence after",N,"iterations") end if;
end do;
return x;
end proc;
jacobi := proc(A::Matrix, b::Vector, x0::Vector, m::integer,
N::integer, tol::float)
...
end;
A:=Matrix([[12.4,0.3,-2.2,0.2,3.6],[1.2,7.1,-1.7,-1.6,0.9],[1.3,3.1,10.8,2.2,0.7],[-1.4,0.8,1.1,-7.7,-1.8],[2.8,6.4,0.0,-1.2,-16.6]]);
b:=Vector([-3.5,19.58,-24.56,8.16,-9.28]);
x0:=Vector([0,0,0,0,0]);
jacobi(A,b,x0,5,100,0.01);
The solution after 8 iterations is:

CASE expression in WHERE clause for diferent and

Can I use case expression to build where like this?
select *
from table
where
case
when x=y then z= j and t=v
when x=k then q= p and s=l
end
;
I need change where clause depending on the value of x variable.
Use or:
select *
from table
where (x = y and z = j and t = v) or (x = k and q = p and s = l);
An alternative to using OR is to use nested CASE statements:
SELECT *
FROM table_name
WHERE CASE
WHEN x = y THEN CASE WHEN z = j AND t = v THEN 1 ELSE 0 END
WHEN x = k THEN CASE WHEN q = p AND s = l THEN 1 ELSE 0 END
ELSE 0
END = 1;
or you could simplify it to:
SELECT *
FROM table_name
WHERE CASE
WHEN x = y AND z = j AND t = v THEN 1
WHEN x = k AND q = p AND s = l THEN 1
ELSE 0
END = 1;
However, you should check whether Oracle can use column indexes or if a separate function-based index is required with these solutions.

Axiomatic Semantics - How to calculate a weakest precondition

Here is example:
x = y + 1;
y = y - 2;
{y < 3}
What is weakest precondition of this example?
I think maybe y < 3 is an answer.
If not, can you tell me why, in detail?
Here is my first mistaken attempt at an answer based on a quick read of Predicate transformer semantics
WP( x := y + 1; y := y - 2, y < 3 ) # Initial problem
= WP( x := y + 1, WP( y := y - 2, y < 3 ) ) # Sequence rule
= WP( x := y + 1, y < 5 ) # Assignment rule
= WP( x - 1 = y, y < 5 ) # solve for y <--- this is wrong!
= WP( x - 1 < 5 ) # Assignment rule
= x < 6 # solve for x
However as pointed out by Kris since x := y + 1 is an assignment to x which doesn't affect y the weakest precondition for y should just be y < 5 so the correct answer should be
WP( x := y + 1; y := y - 2, y < 3 ) # Initial problem
= WP( x := y + 1, WP( y := y - 2, y < 3 ) ) # Sequence rule
= WP( x := y + 1, y < 5 ) # Assignment rule
= y < 5
Thanks also to philipxy for identifying errors in my syntax especially := vs = since that made it easier to mistake assignments for equations which was part of my initial confusion.

For Loop running error

This code doesn't find the correct output
for say n= 1 (although it gives the correct output for say n= 2,3,4..etc.)
if we put n= 1 to find x then the i loop will continue from 1 to 0, hence the first term in x should vanish and leftover should be the second term 5; but it gives 0 ?
Is there any limitation on the input n to run the for loop ?I would appreciate any help.
Function math(n As Integer) As Double
Dim i As Integer
Dim x As Double
For i = 1 To n - 1
x = (n - 1) * 2 + 5
sum = sum + x
Next i
math = sum
End Function
Why not simply:
Function math(n As Integer) As Double
Math = ((n - 1) * 2 + 5) * Abs((n - 1) - (n = 1))
End Function
???
if the answer is correct then Math = (n * 2 + 3) * Abs((n - 1) - (n = 1)) would be easier to understand and make much more sense
In the for loop, if you don't precise the Step, the variable will only increment by 1.
And here, you start at 1 to go to 0, so the loop won't execute, you need to test n to cover both cases :
Function math(n As Integer) As Double
If n < 0 Then Exit Function
Dim i As Integer
Dim x As Double
Dim Summ As Double
Select Case n
Case Is > 1
For i = 1 To n - 1
x = (i - 1) * 2 + 5
Summ = Summ + x
Next i
Case Is = 1
Summ = (n - 1) * 2 + 5
Case Is = 0
Summ = 5
Case Else
MsgBox "This case is not supported", vbInformation + vbOKOnly
Exit Function
End Select
math = Summ
End Function
If n = 1, you end up with For i = 1 To 0 which is incorrect and
should be expressed For i = 1 To 0 STEP -1.
So I suggest you add the STEP BYand make sure it is either 1 to -1 depending on N.