2010-11-22 19 views
13

Bonjour,Combiner deux entiers pour créer un numéro unique

Je cherchais un moyen de combiner deux entiers pour créer un numéro unique, j'ai deux tables que je dois combiner dans une troisième table avec des numéros uniques ,

ce sont mes tables:

Table A 
SchoolID ClassId 
107 56644231 
107 56644532 
107 320110212 

Table B 
SchoolID ClassId 
108 566442310 
108 56644532 
108 50110212 

je dois exporter ces champs à une troisième table combinant ID de classe et ID école dans un champ unique appelé classID. Je dois être en mesure de combiner ces chiffres ensemble et ensuite être en mesure de les combiner pour séparer les élèves et les élèves pour les mettre à jour. Je pensais concaténer les ficelles 'schoolid + '00' + 'classid' puisque je sais que schoolid sera toujours un nombre à 3 chiffres mais je cherche un autre moyen peut-être mathématique où je n'ai pas besoin d'utiliser des moulages de cordes.

Existe-t-il une façon mathématique de le faire? Ou est-ce que le casting est le meilleur moyen de le faire? J'utilise C# pour coder la solution.

Merci,

+4

Veillez à ce que vous ne créez pas un nouveau numéro supérieur à la capacité maximale du type de stockage. – Inisheer

Répondre

14

Semblable à Magnus Hoff, mais je recommanderais d'utiliser une approche binaire amical au lieu d'un ba se 10 approche.

combinedid = (classid << 8) + schoolid; 

Et puis, plus tard:

classid = combinedid >> 8; 
schoolid = combinedid & 0xFF; 

Je pense que cela est un peu plus en avant du point de vue de la programmation linéaire (en précisant que votre ID école est 1 octet (0-255), la l'ID de classe est de 3 octets).

Vous pouvez facilement faire cela avec un bigint (Long/Int64), faisant deux int32 un seul de int64 en toute sécurité:

combinedid = ((long)classid << 32) + schoolid; 
+0

J'aime beaucoup votre réponse. Merci. – jangeador

+2

si classid est un int32 comme mentionné, le code n'est pas correct (classid << 32) sera égal à classid comme il enveloppe. correct serait: UInt64 combiné = classid; combiné << = 32; // maintenant il ne s'enroule pas combiné + = schoolid; – citykid

+0

@thomas - Techniquement, vous avez raison. Je l'ai mis à jour pour lancer classid à long avant le décalage de bits. – userx

2

Vous indiquez que vous travaillez avec une table. Cela m'amène à croire que vous travaillez dans une base de données.

Donc, je dois demander, pourquoi ne pas les stocker dans des colonnes séparées et en faire des clés étrangères simples? Pourquoi créer l'ambiguïté d'essayer de concaténer ou de transformer les nombres avec une équation mathématique? Si vous utilisez une autre table, vous pouvez utiliser un champ d'incrémentation automatique et la combinaison des trois champs (dans l'ordre que vous désignez) vous donnera un identifiant unique.

|------------------- 
| My_combine_table 
|------------------- 
| id | auto_inc 
|------------------- 
| SchoolID | ... 
| SchoolID2 | ... 
+1

J'exporte vers un système tiers dont je n'ai aucun contrôle. Le système local est configuré de sorte que chaque école possède sa propre base de données, donc je ne peux pas contrôler que les classes soient uniques dans toutes les bases de données. Le système tiers n'a pas de place pour schoolId, seul ClassID – jangeador

7
combinedid = classid*1000 + schoolid 

Et puis, plus tard:

classid = combinedid/1000 // Integer division 
schoolid = combinedid % 1000 
+1

Comme @JTA a commenté la question, attention il n'y a pas de débordement. –

2

Si SCHOOLID est toujours un numéro à 3 chiffres se multiplient CLASSID par 1000 puis ajoutez SCHOOLID.

Votre numéro peut "déborder" si., Et étant donné ceux que vous avez s'ils sont 32 bits ils le feront.

+0

Le système attend des entiers de 32 bits, ce qui peut poser un gros problème. Je n'avais pas pensé à ça. Merci de l'avoir signalé. – jangeador

5

Je combiner l'ID comme ceci:

ID = ClassID * 1000 + SchoolID 

Vous pouvez alors obtenir le SchoolID comme ceci:

SchoolID = ID % 1000 

et vous pouvez obtenir le ClassID comme ceci:

ClassID = ID/1000 
1

This SO thread a détaillé d'autres approches mathématiques, certains sont tout simplement mieux. Mais pour votre cas, je soupçonne que ce ne sont pas de bonnes idées. Je dirais que vous devriez enregistrer les deux identifiants dans une troisième table qui a sa propre colonne id unique (clé primaire).