Avatar billede dustie Mester
01. februar 2017 - 16:49 Der er 5 kommentarer og
1 løsning

Udregn sum af tal i array og tal hentet fra database (prepared statement?)

Jeg har uden held prøvet at lave noget kode der ikke bliver hullet som en si og fyldt med spaghetti loops. Jeg håber en venlig sjæl kan hjælpe mig:

Jeg har følgende multidimensional array hvor det første tal er et random id:

Array (
    [680] => Array (
        [name] => Test1
        [amount] => 1
        )
    [517] => Array (
        [name] => Test2
        [amount] => 99
        )
    [1] => Array (
        [name] =>Test3
        [amount] => 12345
        )
)

Og en tabel med:
id (samme som første tal i array (680, 517, ...)
pris
...osv.

Jeg skal have den totale pris regnet ud:
array([amount]) x database(pris) + array([amount]) x database(pris)  ...osv.

Altså i ovenstående eksempel noget i stil med:
1 x 123 +  99 x 456 + 12345 x 789

Jeg tænkter noget i stil med:
<utestet pseudo code eksempel>
foreach ($arr as $key => $value) {
    $ids[$key] = $value['amount'];
    $db_id= implode(',', array_fill(0, count($ids), '?'));
}
SELECT id, pris FROM tabel WHERE `id` IN (' . $db_id. ')
mysqli_stmt_bind_param....... osv. osv.
</pseudo code>

Jeg kan simpelthen ikke få det til at virke efter hensigten. Id i array'et kommer forøvrigt fra $_POST!


(Kan man ikke sætte kode op pænt på Eksperten med tags som i gamles dage? Jeg håber det er overskueligt nok uden.)
Avatar billede arne_v Ekspert
01. februar 2017 - 17:26 #1
Jeg ville nok gribe det lidt anderledes and.

Foerst laese alle id og pris ind fra databasen med en enkelt SELECT til et associativt array $id => $pris.

Og saa beregne udfra de to arrays.

$sum = 0;
foreach ($arr as $key => $value) {
    $sum += ($value['amount'] * $andetarr[$key]);
}
Avatar billede jakobdo Ekspert
01. februar 2017 - 20:37 #2
#1: Hvis vi snakker en tabel med 1 mio records, så kan det vel give fin mening at begrænse udtrækket til kun at indeholde de records der skal arbejdes på.
Altså noget ala: id in (LISTE_OVER_ID'er)
Avatar billede arne_v Ekspert
01. februar 2017 - 20:58 #3
Ja - hvis den tabel er tilbas stor, saa giver det mening at begraense resultatet.

Saa ville jeg lave en afvigelse fra normal best practice og konkatanere id'erne ind i SQL'en.

Loebe gennem $arr og akkumulere alle id og saa ind i SQL.

Og samme beregning som foer.
Avatar billede dustie Mester
01. februar 2017 - 23:17 #4
Jeg er vidst ude på for dybt vand. Jeg kan simpelthen ikke få vendt det rigtigt i mit hoved så det virker. Jeg har følgende:

SELECT id,pris FROM tabel WHERE `id` IN (?,?,?,?)

while ($row = mysqli_fetch_assoc($result)) {
    print_r($row);
}

Array ( [id] => 45 [pris] => 225 ) Array ( [id] => 46 [pris] => 220 ) Array ( [id] => 47 [pris] => 200 ) Array ( [id] => 48 [pris] => 180 )

Så går jeg i stå.
Avatar billede arne_v Ekspert
02. februar 2017 - 01:58 #5
Outline:


<?php
function get_base_data() {
    // real code:
    // <no idea>
    // simulation code:
    return array(680 => array('name' => 'Test1', 'amount' => 1),
                517 => array('name' => 'Test2', 'amount' => 99),
                1 => array('name' => 'Test3', 'amount' => 12345));
}


function extract_ids($arr) {
    return array_keys($arr);
}

function get_prices($ids) {
    // real code:
    $sql = 'SELECT id,pris FROM tabel WHERE `id` IN (' . implode(',', $ids) . ')';
    // execute $sql
    // $res = array();
    // while(something) {
    //    $res[$row['id']] = $row['pris'];
    // }
    // return $res;
    // simulation code:
    return array(680 => 123, 517 => 456, 1 => 789);
}

function calc_total($arr, $prices) {
    $sum = 0;
    foreach($arr as $id => $value) {
        $sum += ($value['amount'] * $prices[$id]);
    }
    return $sum;
}

$arr = get_base_data();
$ids = extract_ids($arr);
$prices = get_prices($ids);
$total = calc_total($arr, $prices);

echo $total;

?>
Avatar billede dustie Mester
02. februar 2017 - 14:58 #6
Super som altid arne_v. Tusinde tak :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester