Mise à jour de la table avec la valeur la plus proche d'une masortingce de search

TABLEAU 1

La première table est la masortingce contenant les valeurs de reference, quelque chose comme ceci:

create table dm_masortingx (x float, z float, avgValue float) insert into dm_masortingx values (1,1, rand()) insert into dm_masortingx values (1,2, rand()) ... insert into dm_masortingx values (4,3, rand()) insert into dm_masortingx values (4,4, rand()) 

Créer une masortingce comme celle-ci

 z\x | 1 | 2 | 3 | 4 | ----------------------------- 1 | .1 | .7 | .3 | .2 | 2 | .5 | .1 | .8 | .6 | 3 | .6 | .2 | .3 | .9 | 4 | .4 | .3 | .3 | .5 | 

TABLEAU 2

La deuxième table est la list des events avec leurs coordonnées:

 create table dm_values (vx float, vz float, v float) insert into dm_values (vx, vz) values (1 + rand()*3, 1 + rand()*3) ... insert into dm_values (vx, vz) values (1 + rand()*3, 1 + rand()*3) 

Ainsi, les inputs ont les coordonnées, mais pas de valeurs pour les events

  vx | vz | v | ----------------------- 1.3 | 2.7 | null | 2.6 | 2.7 | null | 1.3 | 3.3 | null | 1.9 | 1.1 | null | 3.0 | 2.9 | null | ... | ... | ... | 

TÂCHE

Je veux mettre à jour ma deuxième table avec la valeur la plus proche de la première. Donc, pour la première input (x = 1.3, z = 2.7), je voudrais que la valeur soit mise à jour à celle de la masortingce de search où x = 1 et z = 3 (.6). La table mise à jour ressemblerait alors à ceci:

  vx | vz | v | ----------------------- 1.3 | 2.7 | 0.6 | 2.6 | 2.7 | 0.3 | 1.3 | 3.3 | 0.6 | 1.9 | 1.1 | 0.7 | 3.0 | 2.9 | 0.3 | ... | ... | ... | 

PROBLÈME

Je peux get ceci – en théorie – pour travailler avec des sliders. Mais mon TABLEAU 1 a quelques 2000 lignes (~ 50×40) et mes rangs TABLE 2 sont en bas millions. L'approche du slider prendrait des jours, des semaines ou des mois à compléter. J'ai besoin d'une solution plus performante et je suis reconnaissant pour tous les conseils.

D'après ce que je peux voir, vous devriez être capable d'effectuer une simple mise à jour en utilisant un JOIN , où vous ROUND les valeurs de vx et vz pour la condition JOIN , performance sage, vous devrez tester cela sur votre set de données cependant.

Voici la méthode de base pour JOIN datatables, notez que j'ai complété les scripts INSERT pour avoir une masortingce complète:

 CREATE TABLE #dm_masortingx ( x FLOAT , z FLOAT , avgValue DECIMAL(2, 1) ) INSERT INTO #dm_masortingx VALUES ( 1, 1, RAND() ) INSERT INTO #dm_masortingx VALUES ( 1, 2, RAND() ) INSERT INTO #dm_masortingx VALUES ( 1, 3, RAND() ) INSERT INTO #dm_masortingx VALUES ( 1, 4, RAND() ) INSERT INTO #dm_masortingx VALUES ( 2, 1, RAND() ) INSERT INTO #dm_masortingx VALUES ( 2, 2, RAND() ) INSERT INTO #dm_masortingx VALUES ( 2, 3, RAND() ) INSERT INTO #dm_masortingx VALUES ( 2, 4, RAND() ) INSERT INTO #dm_masortingx VALUES ( 3, 1, RAND() ) INSERT INTO #dm_masortingx VALUES ( 3, 2, RAND() ) INSERT INTO #dm_masortingx VALUES ( 3, 3, RAND() ) INSERT INTO #dm_masortingx VALUES ( 3, 4, RAND() ) INSERT INTO #dm_masortingx VALUES ( 4, 1, RAND() ) INSERT INTO #dm_masortingx VALUES ( 4, 2, RAND() ) INSERT INTO #dm_masortingx VALUES ( 4, 3, RAND() ) INSERT INTO #dm_masortingx VALUES ( 4, 4, RAND() ) SELECT * FROM #dm_masortingx CREATE TABLE #dm_values ( vx DECIMAL(2, 1) , vz DECIMAL(2, 1) , v FLOAT ) INSERT INTO #dm_values ( vx, vz ) VALUES ( 1 + RAND() * 3, 1 + RAND() * 3 ) INSERT INTO #dm_values ( vx, vz ) VALUES ( 1 + RAND() * 3, 1 + RAND() * 3 ) SELECT * FROM #dm_values -- replace this SELECT with the UPDATE commands below to update values SELECT v.vx , v.vz , m.avgValue FROM #dm_values v INNER JOIN #dm_masortingx m ON ROUND(v.vx, 0) = mx AND ROUND(v.vz, 0) = mz DROP TABLE #dm_masortingx DROP TABLE #dm_values 

Et pour la mise à jour vous feriez quelque chose comme ceci:

 UPDATE v SET vv = m.avgValue FROM #dm_values v INNER JOIN #dm_masortingx m ON ROUND(v.vx, 0) = mx AND ROUND(v.vz, 0) = mz SELECT * FROM #dm_values 

Produit:

Masortingce:

 xz avgValue 1 1 0.6 1 2 0.9 -- row 2 below 1 3 0.4 1 4 0.5 2 1 0.7 2 2 0.4 2 3 0.5 -- row 1 below 2 4 0.5 3 1 0.4 3 2 0.1 3 3 0.3 3 4 0.8 4 1 0.1 4 2 1.0 4 3 0.5 4 4 0.5 

Valeurs:

 vx vz v 1.8 2.8 NULL -- x = 2, z = 3 1.3 1.5 NULL -- x = 1, z = 2 

Après la mise à jour:

 vx vz v 1.8 2.8 0.5 1.3 1.5 0.9 

REMARQUE:

J'ai changé le type de données à DECIMAL(2, 1) pour les besoins de ce post, vous devrez peut-être modifier cela en fonction de votre jeu de données réel.

Je pense que vous devriez utiliser cross apply ou une sous-requête corrélée pour cela.

 update t2 set v = m.avgvalue from t2 cross apply (select top 1 m.* from dm_masortingx order by square(mx - t2.vx) + square(mz - t2.vz) ); 

Je ne suis pas sûr de la fonction que vous utilisez pour la distance, mais la distance euclidienne semble être une interprétation raisonnable.