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 |
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 | ... | ... | ... |
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 | ... | ... | ... |
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.