J'ai deux tableaux, chacun contenant des numéros de sécurité sociale correspondants. Je veux randomiser les SSN tout en les gardant identiques.

SET @NewSSN  = 000000000 + FLOOR((CAST(ABS(CHECKSUM(NEWID())) AS FLOAT) / 2147483648) * (999999999 - 000000000)) 

Je voudrais prendre cette valeur et mettre à jour les deux tables, correspondant aux SSN d'origine. Pseudo code, j'ai essayé plusieurs variantes de ceci:

UPDATE Table1, Table2
SET [Table1].[SocSecNum], [Table2].[SocSecNum] = @NewSSN
WHERE [Table1].[SocSecNum] = [Table2].[SocSecNum]

Une direction où je peux faire fonctionner cela?

1
Blaze 23 mai 2018 à 17:54

3 réponses

Meilleure réponse

L'idée de Paul d'une table de consultation est tout à fait raisonnable. Cependant, il présente quelques défauts. Par exemple, des doublons sont possibles. Ils sont hautement improbables si vos tables comportent 10 ou 100 lignes. Ils sont beaucoup plus probables s'ils en ont 10 000 000 ou 100 000 000.

De plus, il suppose que toutes les valeurs de table2 sont dans table1. Et, il a un problème si table1 ou table2 a des numéros de sécurité sociale en double.

Donc, je suggérerais simplement d'utiliser des nombres séquentiels, de randomiser l'ordre, de combiner les données des deux tables et de supprimer les doublons:

select SocSecNum,
       right('000000000' + cast(row_number() over (order by newid()) as varchar(255)), 9) as new_SocSecNum
into #SsnMap
from (select SocSecNum
      from Table1
      union  -- on purpose to remove duplicates
      select SocSecNum
      from Table2
     ) s;

update t1
    set SocSecNum = new_SocSecNum
    from Table1 t1 join
         #SsnMap s
         on t1.SocSecNum = s.SocSecNum;

update t2
    set SocSecNum = new_SocSecNum
    from Table2 t2 join
         #SsnMap s
         on t2.SocSecNum = s.SocSecNum;
1
Gordon Linoff 23 mai 2018 à 15:41

Créez une table de références croisées qui mappe les anciens SSN aux valeurs aléatoires, puis exécutez des requêtes update séparées vers Table1 et Table2 pour définir les nouveaux SSN.

create table #SsnMap (OldSsn <datatype>, NewSsn <datatype>)

insert into #SsnMap (OldSsn)
select SocSecNum
from Table1
union -- distinct!
select SocSecNum
from Table2

update #SsnMap
set NewSsn = [random logic here]

update Table1
set SocSecNum = NewSsn
from #SsnMap
inner join Table1
    on SocSecNum = OldSsn

update Table2
set SocSecNum = NewSsn
from #SsnMap
inner join Table2
    on SocSecNum = OldSsn
2
Paul Williams 23 mai 2018 à 21:21

Juste une autre option, vous pouvez utiliser HashBytes () pour créer une carte cohérente.

Deux mises à jour simples sans avoir besoin d'une carte temporaire.

Exemple

Declare @YourTable table (SSN varchar(25))
Insert Into @YourTable values
('555667777'),
('123456789')

Select SSN
      ,Masked = abs(cast(HashBytes('MD5',SSN) as int))
 From @YourTable

Résultats

SSN         Masked
555667777   246591824
123456789   459427083
0
John Cappelletti 23 mai 2018 à 15:43