Pour commencer par la façon laide: vous pouvez aplatir le calcul dans la requête. C'est-à-dire, tournez for i in ... sum(min(...)/abs(...))
en SQL fonctionnant sur chacun des champs. Notez que MIN
et SUM
sont des fonctions agrégées que vous ne voulez pas utiliser. Utilisez plutôt +
pour SUM et IF(a < b, a, b)
pour MIN
. ABS(a, b)
ressemble à IF(a < b, b-a, a-b)
. Si vous venez de calculer la distance euclidienne, vous pourriez faire
SELECT left.user, right.user,
SQRT((left.x-right.x)*(left.x-right.x)
+ (left.y-right.y)*(left.y-right.y)
+ (left.z-right.z)*(left.z-right.z)) as dist
FROM (
SELECT *
FROM dataset.table1 AS left
CROSS JOIN dataset.table1 AS right)
La plus belle façon est des fonctions définies par l'utilisateur, et de créer des vecteurs comme des valeurs répétées. Vous pouvez ensuite écrire une fonction DISTANCE()
qui effectue votre calcul sur les deux tableaux à gauche et à droite de la jointure croisée. Si vous ne participez pas au programme bêta UDF et que vous souhaitez vous joindre à nous, veuillez contacter l'assistance google cloud.
Enfin, si vous changez votre schéma {user:string, field1:float, field2:float, field3:float,...}
-{user:string, fields:[field:float]}
Vous pouvez ensuite aplatir le champ avec la position et faire la jointure croisée sur ce point. Comme dans:
SELECT
user,
field,
index,
FROM (FLATTEN((
SELECT
user,
fields.field as field,
POSITION(fields.field) as index,
from [dataset1.table1]
), fields))
Si vous enregistrez cela comme une vue, appelez « dataset1.flat_view »
Ensuite, vous pouvez faire votre rejoindre:
SELECT left.user as user1, right.user as user2,
left.field as l, right.field as r,
FROM dataset1.flat_view left
JOIN dataset1.flat_view right
ON left.index = right.index
WHERE left.user != right.user
Cela vous donnera une ligne chaque pour chaque paire d'utilisateurs et chaque champ correspondant. Vous pouvez l'enregistrer en tant que vue "dataset1.joined_view".
Enfin, vous pouvez faire vos agrégations:
Puisque vous voulez ceci:
sum(min(user1_row[i], user2_row[i])/abs(user1_row[i] - user2_row[i]))
il ressemblerait à ceci:
SELECT user1, user2,
SUM((if (l < r, l, r))/(if (l > r, l-r, r-l))
FROM [dataset1.joined_view]
GROUP EACH BY user1, user2