Zufällige Zuweisung von Datensätzen

Nessus

Mitglied
Hallo,

ich habe folgendes Problem.
In einer Tabelle sind die Datensätze div. Mitarbeiter mit Adressen etc.
In einer 2ten Tabelle sind div. Adressdaten. Diese sollen nun in einer Abfrage per Zufallsprinzip an die Mitarbeiter zugewiesen werden.
Es können in der 2ten Tabelle x Datensätze sein, die nun einigermaßen gleichmäßig den Mitarbeitern (Gekennzeichnet durch eine Mitarbeiternummer) verteilt werden und in die erste Tabelle geschrieben werden.
Wie löse ich das am besten?
Hat jemand zufällig ein Beispielscript?

Wäre suuuuuuuper, danke!

Grüße an alle Helfer ;-)

Chris
 
Du brauchst eine weitere Tabelle, in der die Verbindungen gespeichert sind.
Die Felder sind mitarbeiter_id und adresse_id

Die Umsetzung kannst du etwa so machen
PHP:
//Meine Testdaten -> Simulation der DB
$mitarbeiter[] = array('id'=> 11, 'name' => 'Hans');
$mitarbeiter[] = array('id'=> 22, 'name' => 'Peter');
$mitarbeiter[] = array('id'=> 33, 'name' => 'Sepp');

$adressen[] = array('id' => 1, 'anschrift' => 'Adresse 1');
$adressen[] = array('id' => 2, 'anschrift' => 'Adresse 2');
$adressen[] = array('id' => 3, 'anschrift' => 'Adresse 3');
$adressen[] = array('id' => 4, 'anschrift' => 'Adresse 4');
$adressen[] = array('id' => 5, 'anschrift' => 'Adresse 5');
$adressen[] = array('id' => 6, 'anschrift' => 'Adresse 6');
$adressen[] = array('id' => 7, 'anschrift' => 'Adresse 7');
$adressen[] = array('id' => 8, 'anschrift' => 'Adresse 8');

//Die IDS extrahieren
foreach($mitarbeiter as $m)     $mitarbeiterIDs[]   = $m['id'];
foreach($adressen as $ad)       $adressenIDs[]      = $ad['id'];

//Beide Listen kräftig schütteln
shuffle($mitarbeiterIDs);
shuffle($adressenIDs);

//min. Anzahl Adresse pro Mitarbeiter ermitteln
$sizeOfGroup = floor(count($adressenIDs)/count($mitarbeiterIDs));
//Die Adressen aufteilen
$groups = array_chunk($adressenIDs, $sizeOfGroup);

//Wenn es nicht aufgeht, haben wir jetzt einen Haufen zuviel
if(count($groups) > count($mitarbeiterIDs)){
    //Restliche Adressen extrahieren
    $rest = array_pop($groups);    
    //und auf die vorherigen Haufen verteilen. Einige Haufen haben jetzt 1 Eintrag weniger als andere
    foreach($rest as $index => $id){
        $groups[$index][] = $id;
    }
}

//Die Gruppen nun den Mitarbeiter zuordnen
$groups = array_combine($mitarbeiterIDs, $groups);

//Und ausgeben (in deinem Fall in ein SQL packen
foreach($groups as $mitarebiterID => $group){
    foreach($group as $adressID){
        echo "{$mitarebiterID}: {$adressID}<br />\n";
    }
}
 
Hi,

vielen Dank ;-)
Ich würde nur ungerne eine weitere Tabelle einfügen. Die Datensätze sollten lediglich in Tabelle 1 eingefügt werden. Das ist eine schlichte Tabelle wo alles drin steht :-)
Wie kann ich das lösen?

Viele Grüße

Chris
 
Und wie stellst du dir das vor?

Der Mitarbeiter 11 in einem Beispiel, kriegt 3 Aufgaben. Soll da jetzt 3 Zeilen entstehen und in allen steht Mitarbeiter 11?

Normalisieren nennt man das mit den 3 Tabellen. es ist die sauberste Art sowas zu realisieren.
 
Hi,

das ist mir schon klar. Das Problem ist nur, das ich dann noch zig Masken ändern müsste, das wäre der Aufwand sicher nicht wert. Außerdem ist die Tabelle mit ca. 100-200 Datensätzen recht übersichtlich :-)

Grüße

Chris
 
Nun, es ist ja nicht mein Problem wie du sie speichern willst ohne Mehrfachdaten zu bekommen.

Das Mischen und aufteilen habe ich dir gezeigt. Du musst es nur noch irgendwie in deine Datenstruktur quetschen
 
Es entstehen doch keine Mehrfachdaten, man ordnet einfachen einen Agenten der Adresse zu und speichert seine ID dort. Das widerspricht auch nicht der normal Form.

Habs mal Simuliert ...

Mitarbeiter:
Code:
+----+------+
| id | name |
+----+------+
|  1 | Foo  |
|  2 | Bar  |
|  3 | Baz  |
+----+------+

Adressen:
Code:
+----+----------+------+
| id | adresse  | ma   |
+----+----------+------+
|  1 | FooBar   |    2 |
|  2 | FooBar 2 |    1 |
|  3 | FooBar   |    3 |
|  4 | FooBar 2 |    2 |
|  5 | FooBar 3 |    3 |
|  6 | FooBar 4 |    1 |
|  7 | FooBar 5 |    2 |
|  8 | FooBar 6 |    2 |
|  9 | FooBar 7 |    2 |
| 10 | FooBar 8 |    3 |
| 11 | FooBar 9 |    3 |
+----+----------+------+

Mit dem Query kannst du die Adressen zufällig zuordnen:
SQL:
UPDATE `ad`
SET `ma`=(SELECT `id` FROM `ma` ORDER BY RAND() LIMIT 1)
 
Zuletzt bearbeitet von einem Moderator:
Das mit dem Zuordnen stimmt.

Aber dein SQL ist ev. unsauber.
Die Analyse zeigt, dass so der ma 1 2 Adressen bekommen hat, der ma 2 hat deren 5 und 3 hat 4.
Sauber verteilt währe, dass 2 der Mitarebiter 4 Aufträge und einer 3 Aufträge kriegt.
 
Es ist halt nach dem Zufallsprinzip, wenn die Verteilung gleichmäßig sein sollte muss man es nach einem System durchnummerieren. Sollte aber auch kein Problem sein.
 
Das mit dem Zuordnen stimmt.

Aber dein SQL ist ev. unsauber.
Die Analyse zeigt, dass so der ma 1 2 Adressen bekommen hat, der ma 2 hat deren 5 und 3 hat 4.
Sauber verteilt währe, dass 2 der Mitarebiter 4 Aufträge und einer 3 Aufträge kriegt.

OK da mir etwas langweilig war, SQL Versuch Nr. 2.

SQL:
SELECT COUNT(`id`) FROM `ad` INTO @anzAd;
SELECT COUNT(`id`) FROM `ma` INTO @anzMa;
SET @reihe:=0;
SET @stmt:=CONCAT('UPDATE `ad` SET `ma`=ELT(CEIL((@reihe:=@reihe+1)/@anzAd*@anzMa),',
	(SELECT GROUP_CONCAT(`id`) FROM `ad`),
	') ORDER BY RAND()');
PREPARE STMT FROM @stmt;
EXECUTE STMT;

Die Ausgabe ist dann ungefähr so:
Code:
+----+-----------+------+
| id | adresse   | ma   |
+----+-----------+------+
|  1 | FooBar 1  |    2 |
|  2 | FooBar 2  |    3 |
|  3 | FooBar 3  |    1 |
|  4 | FooBar 4  |    1 |
|  5 | FooBar 5  |    2 |
|  6 | FooBar 6  |    3 |
|  7 | FooBar 7  |    1 |
|  8 | FooBar 8  |    3 |
|  9 | FooBar 9  |    3 |
| 10 | FooBar 10 |    1 |
| 11 | FooBar 11 |    2 |
| 12 | FooBar 12 |    3 |
| 13 | FooBar 13 |    1 |
| 14 | FooBar 14 |    2 |
| 15 | FooBar 15 |    2 |
| 16 | FooBar 16 |    2 |
| 17 | FooBar 17 |    3 |
| 18 | FooBar 18 |    1 |
| 19 | FooBar 19 |    3 |
+----+-----------+------+

Und die Verteilung ist nun gleichmäßig, soweit wie möglich:
Code:
+------+----------------+
| ma   | Adressen je Ma |
+------+----------------+
|    1 |              6 |
|    2 |              6 |
|    3 |              7 |
+------+----------------+
 
Zuletzt bearbeitet von einem Moderator:
Zurück