Dator, MOBO: Asus X99-A, CPU: Intel I7 6800k (3.4GHz), GPU: Geforce PNY 2070 Super, RAM: 4x8GB Corsair Vengeance LPX 2400MHz, OS-HDD: Intel 750 PCIe 400GB, PSU: EVGA SuperNOVA G2 850W
PHP/SQL - hämta och sortera anställda
Jag har ett problem. Jag har en tabell där jag sätter anställda till olika avdelningar som heter crosstable.
Jag vill få ut den/dom som har minst antal rader (minst kompabilitet mot en avdelning) och det är inga problem.
Problemet uppstår när det är fler än 1 som har samma antal, då visar min hämtning bara den som ligger först i databasen.
Hur bör jag gå tillväga för att få ut alla 'person_id' som har lägst rader i min tabell?
Sedan vill jag slumpa fram en av dom här som jag placerar i en avdelning som dom är kompatibla mot.
<?php
include "conn.php";
include "functions.php";
countCompatible($mysqli);
$result = mysqli_query($mysqli,"SELECT *, COUNT(*) as antal FROM crosstable GROUP BY person_id;");
while($row = mysqli_fetch_array($result))
{
echo "<b>Person: ".$row['person_id']." Antal: ".$row['antal']."</b><br>";
$array[$row['person_id']] = $row['antal'];
}
$lowestSections = min($array);
$test = array_search('1', $array);
//Här vill jag få ut "Den/dom här personerna har lägst antal kompatibla avdelningar"
echo "<br>Den här personen ".$test." har lägst antal kompatibla avdelningar";
?>
[/php]
Hej,
Om du bara vill få ut den personen med lägst antal rader borde du kunna sortera och begränsa det direkt i sql frågan genom SORT BY ASC (ASC = Ascending dvs lägst till högst), typ någonting sånt här:
<?php
include "conn.php";
include "functions.php";
countCompatible($mysqli);
$result = mysqli_query($mysqli,"SELECT *, COUNT(*) as antal FROM crosstable GROUP BY person_id ORDER BY antal ASC LIMIT 1;");
$row = mysqli_fetch_array($result);
echo "<br>Den här personen ".$row['person_id']." har lägst antal kompatibla avdelningar";
?>
Jag skulle behöva hjälp av någon som kan ta sig tid att läsa igenom min kod och förklara varför den inte placerar ut alla anställda till avdelningarna. Jag upptäckte att den ibland betedde sig annorlunda när jag refreshade sidan, istället för att "refresha" loopen i koden. Någon gång ibland placerar den ut alla, men senaste gångerna har den lämnat 3 stycken utan avdelning, och inte tagit hänsyn till att vissa avdelningar stått tomma.
Filen som genererar och placerar anställda till olika avdelningar
<?php
include "conn.php";
include "functions.php";
if(isset($_POST['reset'])) {
$panic = "UPDATE personer SET booked=0";
mysqli_query($mysqli, $panic);
$panic2 = "UPDATE avdelningar SET max=0";
mysqli_query($mysqli, $panic2);
}elseif(isset($_POST['save'])) {
//Backup "generate" to table 'avdelningar' (=sections in swedish) "lastsection" to prevent employee to end up at the same section as yesterday
backupToLastSection($mysqli);
}
?>
<html>
<form action="generate.php" method="post">
<input type=submit name="reset" value="Reset">
</form>
</html>
<?php
$sql = "UPDATE avdelningar SET max = 0}";
mysqli_query($mysqli, $sql);
//Main loop, loop until all sections are filled with employees
$loopstatus = true;
//Counter, how many times it should take to complete the task, i need to find another solution
$v = 0;
while($loopstatus)
{
$array = [];
$v = $v + 1;
//Check if all sections are filled with employees
$test = "SELECT * FROM avdelningar";
$test2 = (mysqli_query($mysqli, $test));
while($rowe = mysqli_fetch_array($test2))
{
//If all sections are NOT filled with employees
if($rowe['max'] == '0')
{
echo "Om alla avdelningar INTE är tillsatta<br>";
$loopstatus = true;
}
//Group number of unique person_id in crosstable
$result = mysqli_query($mysqli,"SELECT *, COUNT(*) as antal FROM crosstable GROUP BY person_id;");
//Loop number of unique person_id in crosstable, number of people that are available for any sections
//Create array containing employee id[number of available sections]
while($row = mysqli_fetch_array($result))
{
//Get number from 'crosstable' count by 'sum person_id as group'
$result2 = "SELECT * FROM personer WHERE id = {$row['person_id']}";
$resultat = mysqli_fetch_assoc(mysqli_query($mysqli, $result2));
if($resultat['booked'] == 0 && $resultat['away'] == 0)
{
$array[$row['person_id']] = $row['antal'];
echo "Om resultat bokad = 0 och away = 0: Person ID ".$row['person_id']." och Antal ".$row['antal']."<br>";
}
}
//If not all employees are assigned a section, in other words if the array is NOT empty
if(count($array) > 0)
{
//Count people with lowest number of sections in crosstable
$employeeLowestSectionCount = array_keys($array, min($array));
echo "employeeLowestSectionCount ";
print_r($employeeLowestSectionCount);
$adaptedcount = count($employeeLowestSectionCount);
echo "<br>adaptedcount: ".$adaptedcount."<br>";
//Variabel that contains number of people with lowest number of compatible sections
if($adaptedcount != 0)
{
//Random employee
$random = rand(0, ($adaptedcount - 1));
echo "Random: ".$random."<br>";
//Random section id
$result3 = "SELECT section_id FROM crosstable WHERE person_id={$employeeLowestSectionCount[$random]} ORDER BY RAND() LIMIT 1";
$query = mysqli_fetch_assoc(mysqli_query($mysqli, $result3));
if(checkSectionNotFull($mysqli, $query['section_id']) == false)
{
$connstring2 = "SELECT * FROM avdelningar WHERE id = {$query['section_id']}";
$data2=mysqli_fetch_assoc(mysqli_query($mysqli, $connstring2));
//If section has NOT been assigned max number of employees(1=section full or 0=not full)
if($data2['max'] == 0) {
echo "Det fanns plats på avdelning".$query['section_id']." för ".$employeeLowestSectionCount[$random]." Uppdaterar DB!<br><br>";
//Update database
writeToDatabase($mysqli, $query['section_id'], $employeeLowestSectionCount[$random]);
}else
{
echo "Fanns ej plats, uppdaterar ej DB!<br><br>";
}
}else
{
//Update section to status "full"
$sql = "UPDATE avdelningar SET max = 1 WHERE id = {$query['section_id']}";
mysqli_query($mysqli, $sql);
//Check if the code/program is "satisfied" with all employee assignments
if(checkAllAssigned($mysqli) == 1)
{
$loopstatus = false;
echo "Uppfyllda!!";
}
}
}
}else
{
$loopstatus = false;
echo "Det verkar vara slut!";
}
}
//There must be some kind of "LIMIT" if the program cant achieve an optimal combination of employees / sections
//I really don't know how to set this, so I just wrote one temporarily manually
if($v > 70) {
echo "<script>window.location.replace('generate.php');</script>";
echo "Antal gånger programmet har körts: ".$v;
}
if($loopstatus = false)
{
?>
<script>
window.location.replace("index.php");
</script>
<?php
}
}
?>
Mina funktioner
<?php
include "conn.php";
function checkAllAssigned($mysqli) {
//Räkna antalet totala platser på alla avdelningar
$sql = "SELECT SUM(platser) as 'antal' FROM avdelningar";
$query = mysqli_query($mysqli, $sql);
$antalPlatser = mysqli_fetch_array($query);
//Räkna antal bokade personer
$sql = "SELECT COUNT(*) as antal FROM personer WHERE booked != 0";
$query = mysqli_query($mysqli, $sql);
$antalBokade = mysqli_fetch_assoc($query);
//Räkna antalet tillgängliga personer
$sql = "SELECT COUNT(*) as antal FROM personer WHERE booked = 0 AND away = 0";
$query = mysqli_query($mysqli, $sql);
$antalAvail = mysqli_fetch_assoc($query);
//Om antalet bokade personer är lika med totala antalet platser
if($antalBokade['antal'] == $antalPlatser['antal']){
return 1;
//Om antalet tillgängliga personer är mindre än totala antalet platser OCH antal bokade är lika med antalet tillgängliga
}elseif($antalAvail['antal'] < $antalPlatser['antal'] && $antalBokade['antal'] == $antalAvail['antal']) {
return 1;
//Om antalet tillgängliga personer är fler än totala antalet platser
}elseif($antalAvail['antal'] > $antalPlatser['antal'] && $antalBokade['antal'] == $antalPlatser['antal']) {
return 1;
}else {
return 0;
}
}
function checkSectionNotFull($mysqli, $section) {
//Hämta från avdelningar
$test1 = mysqli_query($mysqli, "SELECT * FROM avdelningar");
while($rad = mysqli_fetch_array($test1)) {
if($section == $rad['id']) {
echo "Avd id: ".$rad['id']." <br>Antal platser avdelning ".$rad['platser']." <br>";
//Räkna hur många som är bokade till varje avdelning
$result = mysqli_query($mysqli,"SELECT *, COUNT(*) as antal FROM personer WHERE booked = {$rad['id']} GROUP BY booked LIMIT 1;");
while($rad2 = mysqli_fetch_array($result)) {
if($rad['platser'] - $rad2['antal'] == 0) {
return true;
}else {
return false;
}
}
}
}
}
function writeToDatabase($conn, $booked, $id) {
$dbString = "UPDATE personer SET booked = {$booked} WHERE id = {$id}";
echo $dbString;
mysqli_query($conn, $dbString) or die();
}
//Räkna antal totala personer som är kompatibla mot någon avdelning
function countCompatible($conn) {
$lowestSections = "SELECT COUNT(DISTINCT person_id) as number FROM crosstable";
$result = mysqli_query($conn, $lowestSections);
while($row = mysqli_fetch_array($result)) {
return $row['number'];
}
}
function backupToLastSection($mysqli) {
$sqlcopy = "UPDATE personer SET lastsection = booked";
mysqli_query($mysqli, $sqlcopy);
}
//SELECT count(*) as total from personer
function countSQL($db, $connstring) {
$connstring = mysqli_query($db, $connstring);
$data=mysqli_fetch_assoc($connstring);
return $data['total'];
}
function updateSQL($db, $updatestring) {
if ($db->query($updatestring) === TRUE) {
echo "Uppdatering \"".$updatestring."\" genomförd!";
} else {
echo "Uppdateringen \"".$updatestring."\" misslyckades!" . $conn->error;
}
}
function randSection($db, $id) {
$resultpeople = mysqli_query($db,"SELECT * FROM personer WHERE id = {$id}");
$resultsections = mysqli_query($db,"SELECT * FROM avdelningar");
$countpeople = countSQL($db, "SELECT count(*) as total from personer");
$countsections = countSQL($db, "SELECT count(*) as total from avdelningar");
while($row = mysqli_fetch_array($resultpeople))
{
for($i=1; $i <= $countpeople; $i++) {
echo "<br>i: ".$i."";
}
}
while($row2 = mysqli_fetch_array($resultsections)) {
echo "<br>Platser: ".$row2['platser'];
}
for($j=1; $j <= $countsections; $j++) {
echo "<br>j: ".$j."";
}
}
?>
[...]Jag upptäckte att den ibland betedde sig annorlunda när jag refreshade sidan, istället för att "refresha" loopen i koden. Någon gång ibland placerar den ut alla, men senaste gångerna har den lämnat 3 stycken utan avdelning, och inte tagit hänsyn till att vissa avdelningar stått tomma.
Här har du egentligen en ganska bra idé om var och hur någonting går fel.
Nu har jag bara ögat igenom koden lite, men baserat på det du säger så låter det som att det är någon UPDATE som spökar och sätter in värden på någon form av felaktigt sett.
Börja med att titta där den ska skriva ut avdelning (och speciellt den plats som skriver ut om det är tomt) och börja söka baklänges.
Hett tips kan vara att tömma testdata och köra om det från scratch för att kunna reproducera buggen, undelättar felsökningen enormt.
Lycka till!
Dator, MOBO: Asus X99-A, CPU: Intel I7 6800k (3.4GHz), GPU: Geforce PNY 2070 Super, RAM: 4x8GB Corsair Vengeance LPX 2400MHz, OS-HDD: Intel 750 PCIe 400GB, PSU: EVGA SuperNOVA G2 850W
Eller kan det vara den funktionen som kollar om alla avdelningar är satta? Kolla gärna på den också om jag har satt alla villkor rätt!
Skickades från m.sweclockers.com
Nu har jag nog lyckats åtgärda felet och den verkar placera ut folk som den ska äntligen!
Nu återstår två problem som jag hoppas att någon kan hjälpa mig med!
1. Jag behöver ett sätt för loopen att veta om den har fastnat, dvs om sista personen/personerna att slumpas inte har något kompatibel avdelning och att loopen således behöver börja om och slumpa ut alla från början.
2. Att den tar hänsyn till vart man var under gårdagen (eller förra utfallet). Det anges i tabellen "personer" under kolumnen "last_section" och representeras av en siffra som motsvarar kolumnen "id" i tabellen "avdelningar".
Här är den senaste koden:
Edit: jag upptäckte också att den inte verkar uppdatera alla kolumner som säger om en avdelning är fullsatt eller ej (rad 135 i koden).
Men det verkar som att den placerar ut och tar hänsyn till om avdelningen är full ändå, även om inte alla max=0 i tabellen avdelningar.
$sql = "UPDATE avdelningar SET max = 1 WHERE id = {$query['section_id']}";
<?php
include "conn.php";
include "functions.php";
//Om do=generate
if(isset($_POST['reset']) && isset($_GET['do']) == 'generate')
{
$panic = "UPDATE personer SET booked=0";
mysqli_query($mysqli, $panic);
$panic2 = "UPDATE avdelningar SET max=0";
mysqli_query($mysqli, $panic2);
?>
<script>
window.location.replace("generate.php");
</script>
<?php
//Om do=save
}elseif(isset($_POST['save']) && isset($_GET['do']) == 'save')
{
//Backup "generate" to table 'avdelningar' (=sections in swedish) "lastsection" to prevent employee to end up at the same section as yesterday
backupToLastSection($mysqli);
echo "Har sparat!";
//Annars kör programmet
}else
{
?>
<html>
<form action="generate.php?do=generate" method="post">
<input type=submit name="reset" value="Reset">
</form>
</html>
<?php
$sql = "UPDATE avdelningar SET max = 0}";
mysqli_query($mysqli, $sql);
//Main loop, loop until all sections are filled with employees
$loopstatus = true;
//Counter, how many times it should take to complete the task, i need to find another solution
$v = 0;
while($loopstatus)
{
//Check if the code/program is "satisfied" with all employee assignments
if(checkAllAssigned($mysqli) == 1)
{
$loopstatus = false;
echo "checkAllAssigned = 1, bryt loopen!";
}
$v = $v + 1;
//Check if all sections are filled with employees
$test = "SELECT * FROM avdelningar";
$test2 = (mysqli_query($mysqli, $test));
while($rowe = mysqli_fetch_array($test2))
{
//If all sections are NOT filled with employees
if($rowe['max'] == '0')
{
echo "Om alla avdelningar INTE är tillsatta<br>";
}
//Group number of unique person_id in crosstable
$result = mysqli_query($mysqli,"SELECT *, COUNT(*) as antal FROM crosstable GROUP BY person_id;");
$array = [];
//Loop number of unique person_id in crosstable, number of people that are available for any sections
//Create array containing employee id[number of available sections]
while($row = mysqli_fetch_array($result))
{
//Get number from 'crosstable' count by 'sum person_id as group'
$result2 = "SELECT * FROM personer WHERE id = {$row['person_id']}";
$resultat = mysqli_fetch_assoc(mysqli_query($mysqli, $result2));
if($resultat['booked'] == 0 && $resultat['away'] == 0)
{
$array[$row['person_id']] = $row['antal'];
echo "Om resultat bokad = 0 och away = 0: Person ID ".$row['person_id']." och Antal ".$row['antal']."<br>";
}
}
//If not all employees are assigned a section, in other words if the array is NOT empty
if(count($array) > 0)
{
//Count people with lowest number of sections in crosstable
$employeeLowestSectionCount = array_keys($array, min($array));
echo "employeeLowestSectionCount ";
print_r($employeeLowestSectionCount);
$adaptedcount = count($employeeLowestSectionCount);
echo "<br>adaptedcount: ".$adaptedcount."<br>";
//Variabel that contains number of people with lowest number of compatible sections
if($adaptedcount != 0)
{
//Random employee
$random = rand(0, ($adaptedcount - 1));
echo "Random: ".$random."<br>";
//Random section id
$result3 = "SELECT section_id FROM crosstable WHERE person_id={$employeeLowestSectionCount[$random]} ORDER BY RAND() LIMIT 1";
$query = mysqli_fetch_assoc(mysqli_query($mysqli, $result3));
if(checkSectionNotFull($mysqli, $query['section_id']) == false)
{
$connstring2 = "SELECT * FROM avdelningar WHERE id = {$query['section_id']}";
$data2=mysqli_fetch_assoc(mysqli_query($mysqli, $connstring2));
//If section has NOT been assigned max number of employees(1=section full or 0=not full)
if($data2['max'] == 0) {
echo "Det fanns plats på avdelning".$query['section_id']." för ".$employeeLowestSectionCount[$random].", Uppdaterar DB!<br><br>";
//Update database
writeToDatabase($mysqli, $query['section_id'], $employeeLowestSectionCount[$random]);
}else
{
echo "Fanns ej plats, uppdaterar ej DB!<br><br>";
}
}else
{
//Update section to status "full"
$sql = "UPDATE avdelningar SET max = 1 WHERE id = {$query['section_id']}";
mysqli_query($mysqli, $sql);
echo "Uppdatera avdelningar set max 1 där id = ".$query['section_id']."<br>";
}
}
}
}
if($loopstatus == false)
{
echo "Loopen verkar ha fyllt databasen på ".$v."st vändor!";
}
echo "V har körts: ".$v." gång!<br>";
}
?>
<form action="generate.php?do=save" method="post">
Spara? <input type=submit name="save" value="Spara">
</form>
<?php
}
?>
- Igår Intel skyller Raptor Lake-krascher på moderkortstillverkare 30
- Igår TSMC utvecklar enorma kretsar med effekt mätt i kilowatt 11
- Igår Så mycket långsammare blir Intels värstingkretsar med ”Intel Baseline” i BIOS 52
- 26 / 4 Corsair Platform 6: För dig som inte nöjer dig med Ikea-skrivbord 11
- 26 / 4 Rykte: Switch 2 släpps i höst – OLED-variant dröjer 51
- 27 / 4 Stöd för komprimering i fler format på gång till Windows 19
- 27 / 4 Krönika: "Early access" är utstuderad girighet 47
- 27 / 4 Microsoft släpper källkoden till MS‑DOS 4.00 20
- 26 / 4 Ny caps lock-symbol i Windows förbryllar HP-användare 21
- 26 / 4 Därför blockerar Windows 11 24H2 Start‑menyhack 43
- Igår Google nöjda med annonsexperiment: Youtube kan få pausreklam 34
- 27 / 4 Övergivet skadeprogram infekterar miljontals maskiner 19
- 27 / 4 Helgsnack: Är all reklam till ondo? 85
- 26 / 4 NetonNet varnar om läckta kunduppgifter 23
- 26 / 4 Premiär på SweClockers! Månadens drop med gamingskärm hos Elgiganten 74
- Vad lyssnar du på just nu?13904
- Hur skickar man bäst en dator från Skåne till Västerbotten?0
- Gamers Nexus: EK Water Blocks har problem35
- Intel skyller Raptor Lake-krascher på moderkortstillverkare30
- Nyhetstips!429
- Övergivet skadeprogram infekterar miljontals maskiner19
- Fallout 4 Next Gen – Update Notes2
- Escape from Tarkov394
- bluescreen mm0
- Visa dina spelvideor5
- Säljes 4070 TI i5 13400f Dator
- Säljes ASUS ROG Strix 3080 10GB White
- Säljes CoD MW3 ps5 inkl lockpick, Noctua NH-U12S AM4, DAC och HDD
- Säljes Elgato Wave 3 mikrofon
- Säljes TC-Helicon GoXLR Mini
- Säljes Komplett dator, 2700x, GTX 1070
- Säljes Vårstädning - i5-6600, GA-H170N-WIFI, 2x8GB DDR4, GTX 760, Noctua NH-U12S, FD Tesla 650W
- Köpes Uppgraderingspaket am4/am5/lga1700, ssd, gpu
- Säljes Flertal sata SSD'er 480GB-2TB
- Säljes Playstation 5 Digital 825gb
- Google nöjda med annonsexperiment: Youtube kan få pausreklam34
- Intel skyller Raptor Lake-krascher på moderkortstillverkare30
- TSMC utvecklar enorma kretsar med effekt mätt i kilowatt11
- Så mycket långsammare blir Intels värstingkretsar med ”Intel Baseline” i BIOS52
- Stöd för komprimering i fler format på gång till Windows19
- Krönika: "Early access" är utstuderad girighet47
- Övergivet skadeprogram infekterar miljontals maskiner19
- Helgsnack: Är all reklam till ondo?85
- Microsoft släpper källkoden till MS‑DOS 4.0020
- Ny caps lock-symbol i Windows förbryllar HP-användare21
Externa nyheter
Spelnyheter från FZ
- Dragon’s Dogma 2 har sålt så bra att Capcom betalar ut mer pengar till aktieägarna igår
- Silent Hill 2 – Snart avslöjas släppdatum och till vilka plattformar det släpps igår
- River City Girls 2 gästas av Double Dragon i sommar igår
- Sand Land delar en sista hälsning från Akira Toriyama 27/04
- Alien: Rogue Incursion släpps till VR senare i år 27/04