Δημιουργια Συνάρτησης SUM

Σε αυτή την περιοχή μπορείτε να βρείτε ή να αναζητήσετε πληροφορίες σχετικές με την PHP

Συντονιστές: WebDev Moderators, Super-Moderators, PHP Moderators

Απάντηση
Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Δημιουργια Συνάρτησης SUM

Δημοσίευση από dva_dev » 28 Ιουν 2010 20:42

Μάλλον κάτι έχεις κάνει εντελώς στραβά. Λογικά πάνω από 0.001€ απόκλιση δεν θα έπρεπε να έχεις.

Αλλά μιας και αναφέρεις σε τόσο μικρό αριθμό εγγραφών τόση μεγάλη απόκλιση και δεν το έχεις λύσει ακόμα το πρόβλημα, έκανα μια δοκιμαστική βάση με έναν πίνακα βάζοντας περίπου 2εκ τυχαία δεδομένα (όσο γίνεται τυχαία με την RAND() της mysql).
Τρέχοντας κάποια queries ώστε να υπολογίζει η php το άθροισμα των στηλών (1), και το σύνολικό άθροισμα (2), καθώς και τα αντίστοιχα των (1),(2) από τη mysql με τη SUM, τουλάχιστον στα 2 δεκαδικά στρογγυλοποίηση η απόκλιση στα αθροίσματα αυτά είναι 0.00€.

Πριν δοκιμάσεις οτιδήποτε θα έλεγα αν δεν το έχεις κάνει ήδη, να αλλάξεις τα πεδία που κρατάνε τα ποσά από varchar σε double έστω float. Το varchar είναι για να αποθηκεύει κείμενο, ούτε αριθμούς, ούτε ημερομηνίες.

Στη δοκιμαστική βάση ο πίνακας έχει δημιουργηθεί έτσι:

Κώδικας: Επιλογή όλων

CREATE TABLE  `testdb`.`kiniseis` (
  `id` int(11) NOT NULL auto_increment,
  `kinisis_1a` double NOT NULL default '0',
  `kinisis_1b` double NOT NULL default '0',
  `kinisis_1c` double NOT NULL default '0',
  `kinisis_1e` double NOT NULL default '0',
  `100a` double NOT NULL default '0',
  `100b` double NOT NULL default '0',
  `100c` double NOT NULL default '0',
  `100e` double NOT NULL default '0',
  `super_1a` double NOT NULL default '0',
  `super_1b` double NOT NULL default '0',
  `super_1c` double NOT NULL default '0',
  `super_1e` double NOT NULL default '0',
  `95_1a` double NOT NULL default '0',
  `95_1b` double NOT NULL default '0',
  `95_1c` double NOT NULL default '0',
  `95_1e` double NOT NULL default '0',
  `95_2a` double NOT NULL default '0',
  `95_2b` double NOT NULL default '0',
  `95_2c` double NOT NULL default '0',
  `95_2e` double NOT NULL default '0',
  `super_2a` double NOT NULL default '0',
  `super_2b` double NOT NULL default '0',
  `super_2c` double NOT NULL default '0',
  `super_2e` double NOT NULL default '0',
  `kinisis_2a` double NOT NULL default '0',
  `kinisis_2b` double NOT NULL default '0',
  `kinisis_2c` double NOT NULL default '0',
  `kinisis_2e` double NOT NULL default '0',
  `fpa` float NOT NULL default '0',
  `kdate` datetime NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `idx_kdate` (`kdate`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=1;
Εβαλα kdate αντί για date επειδή το date χρησιμοποιείται και σαν keyword.

Ενα δοκιμαστικό run που φέρνει όλα τα δεδομένα στο
http://dvassil.co.cc:800/mysqltest/

Κώδικας: Επιλογή όλων

From Date: 1900-01-01
To Date:   2100-12-31
Records selected: 2,097,152

Records returned > 2000. Will not show actual data.

Printing column sums as calculated by mysql with total sums as calculated by both mysql and php
    #            sum1            sum2            sum3            sum4            sum5            sum6            sum7              rowSum
-----------------------------------------------------------------------------------------------------------------------------------------
    1  445,765,508.21  528,423,175.01  410,401,356.14  488,518,512.29  810,408,763.58  446,259,288.02  475,602,049.92    3,605,378,653.18
-----------------------------------------------------------------------------------------------------------------------------------------
                                                                                                           MySql SUM() = 3,605,378,653.18
                                                                                                           PHP Sum     = 3,605,378,653.18
Η στήλες sum1, sum2, ..., sum7 καθώς και το MySql SUM() υπολογίζονται από τη mysql, ενώ το rowSum και το PHP Sum από την php.
Οπως βλέπεις δεν υπάρχει θέμα απόκλισης.

Αλλά και τα αθροίσματα να μην υπολογίζει η mysql αλλά να βάλουμε την php να το κάνει (πιο αργή διαδικασία βέβαια γι αυτό και το έχω περιορίσει σε 2000 εγγραφές), πάλι δεν υπάρχει τέτοιο θέμα, όπως μπορείς να δεις και μόνος σου.
Αν οι εγγραφές είναι λιγότερες από 2000 θα τις φέρει και θα υπολογίσει και το άθροισμα των στηλών και στην php, φέρνοντας και πιο κάτω τα αντίστοιχα αθροίσματα που υπολογίζει η mysql (για να υπάρχει μέτρο σύγκρισης).

Ενα δοκιμαστικό run δίνοντας από ποιά εώς ποιά ημερομηνία θα τρέξει είναι στο
http://dvassil.co.cc:800/mysqltest/?dat ... 2010-01-05 (περίπου 13-14 ημέρες διαφορά φέρνουν 2000 εγγραφές σύμφωνα με τα δοκιμαστικά δεδομένα που έχω βάλει). Αν το διάστημα έχει πάνω από 2000 εγγραφές δεν τρέχει το κομμάτι που εμφανίζει τα δεδομένα για να μην βαρύνει και αργεί η σελίδα.

Κώδικας: Επιλογή όλων

From Date: 2010-01-03
To Date:   2010-01-05
Records selected: 432

Printing table data and column sums as calculated by php
    #           calc1           calc2           calc3           calc4           calc5           calc6           calc7               kdate
-----------------------------------------------------------------------------------------------------------------------------------------
    1           62.35           38.23          145.79           38.45           71.87           40.10          105.05 2010-01-03 00:00:00
    2           93.74           33.77           17.09           32.90           18.01           55.21           64.45 2010-01-03 00:10:00
    3          178.38           58.06          318.09           88.95          188.70           34.80          112.03 2010-01-03 00:20:00
    4           94.03           94.27           50.48           81.06          203.43           61.03           50.87 2010-01-03 00:30:00
    5           27.10           65.67           35.83           82.33          190.81           33.96           73.94 2010-01-03 00:40:00
    6           19.37           23.29           46.38           26.31            9.37           10.61           28.76 2010-01-03 00:50:00
    7           13.36           17.30           15.75           38.91           19.06            3.66           30.27 2010-01-03 01:00:00
    8           15.33           17.28           24.09           18.58            9.16           18.23           14.60 2010-01-03 01:10:00
    9           69.95          117.01          326.43           64.80          317.72           93.94          258.52 2010-01-03 01:20:00
   10           99.51          145.68          128.57           54.99           94.75           84.40           89.29 2010-01-03 01:30:00
   11           86.86          225.33           34.08           55.34           16.86           72.28           55.94 2010-01-03 01:40:00
...
  427          378.90          202.00          133.11          410.31          106.68          202.33           75.33 2010-01-05 23:00:00
  428          102.96          109.25           98.48          122.28           54.38            2.84           96.21 2010-01-05 23:10:00
  429           27.85          108.71           45.58           30.60           63.83          119.55           82.89 2010-01-05 23:20:00
  430            4.79            9.18           13.83            2.80            3.50            6.74            5.38 2010-01-05 23:30:00
  431           37.26          171.80           43.40           50.40           96.54           79.41          132.47 2010-01-05 23:40:00
  432           59.37          128.53          118.78           79.06          235.54          178.16           49.28 2010-01-05 23:50:00
-----------------------------------------------------------------------------------------------------------------------------------------
SUM =       45,044.11       50,199.16       54,128.98       57,245.93       53,070.65       90,710.04       52,928.02
---------------------------------------------------------------------------------------------------------------------

Printing column sums as calculated by mysql with total sums as calculated by both mysql and php
    #            sum1            sum2            sum3            sum4            sum5            sum6            sum7              rowSum
-----------------------------------------------------------------------------------------------------------------------------------------
    1       45,044.11       50,199.16       54,128.98       57,245.93       53,070.65       90,710.04       52,928.02          403,326.89
-----------------------------------------------------------------------------------------------------------------------------------------
                                                                                                                 MySql SUM() = 403,326.89
                                                                                                                 PHP Sum     = 403,326.89
Τα σύνολα των στηλών στη γραμμή SUM = ... υπολογίζονται από την PHP, ενώ τα σύνολα από κάτω (sum1, sum2, ... sum7) από τη mysql.
Το rowsum και το PHP Sum από την php, ενώ το MySql SUM() από τη Mysql. Οπως βλέπεις καμία διαφορά και εδώ, άρα δεν υπάρχει θέμα απόκλισης λόγω στρογγυλοποίησης (όχι τουλάχιστον στα 2-3 πρώτα δεκαδικά. Ισως από το 4ο δεκαδικό και μετά να υπάρχει κάποια διαφορά).

Δοκιμαστικά δεδομένα υπάρχουν από 1974-12-31 ως 2014-11-14 (2,097,152 εγγραφές. Φτάνουν για αρκετές δοκιμές :D)
Αν δωθούν παράμετροι πρέπει να δωθούν σε μορφή ΕΕΕΕ-ΜΜ-ΗΗ ή ΕΕΕΕΜΜΗΗ (χωρίς παύλες), αλλιώς .
Αν δεν δωθεί date1 θεωρεί παίρνει default το '1900-01-01', αντίστοιχα για το date2 το '2100-12-31'.

Ο κώδικας που τρέχει στο http://dvassil.co.cc:800/mysqltest/?source είναι:

Κώδικας: Επιλογή όλων

<?php 
    header&#40;'Content-Type&#58; text/plain; charset=utf-8'&#41;; 

    $date1 = isset&#40;$_GET&#91;'date1'&#93;&#41; ? strftime&#40;'%Y-%m-%d', strtotime&#40;$_GET&#91;'date1'&#93;&#41;&#41; 
                                   &#58; '1900-01-01'; 
    $date2 = isset&#40;$_GET&#91;'date2'&#93;&#41; ? strftime&#40;'%Y-%m-%d', strtotime&#40;$_GET&#91;'date2'&#93;&#41;&#41; 
                                   &#58; '2100-12-31'; 

    $con = mysqli_connect&#40;DB_SERVER, DB_USER, DB_PASSWORD, DB_DATABASE, DB_SERVER_PORT&#41;; 

    $date1 = mysqli_real_escape_string&#40;$con, $date1&#41;; 
    $date2 = mysqli_real_escape_string&#40;$con, $date2&#41;; 
    echo "From Date&#58; $date1\n"; 
    echo "To Date&#58;   $date2\n"; 

    //We have DATETIME in our database, so add appropriate times. 
    $date1 .= ' 00&#58;00&#58;00'; 
    $date2 .= ' 23&#58;59&#58;59'; 

    $query = 'SELECT COUNT&#40;*&#41; FROM kiniseis WHERE `kdate` BETWEEN ? AND ?'; 
    $stmt = mysqli_prepare&#40;$con, $query&#41;; 
    mysqli_stmt_bind_param&#40;$stmt, 'ss', $date1, $date2&#41;; 
    mysqli_stmt_execute&#40;$stmt&#41;; 
    mysqli_stmt_bind_result&#40;$stmt, $records&#41;; 
    mysqli_stmt_fetch&#40;$stmt&#41;; 
    &#123; 
        echo 'Records selected&#58; ', number_format&#40;$records,0&#41;, "\n\n"; 
    &#125; 
    mysqli_stmt_close&#40;$stmt&#41;; 

    $showLimit = 2000; 
    if &#40;$records > $showLimit&#41; 
    &#123; 
        print&#40;"Records returned > $showLimit. Will not show actual data.\n"&#41;; 
    &#125; 
    else 
    &#123; 
        //Calculate total sum using MySql SUM&#40;...&#41; 
        $query = ' 
            SELECT 
                SUM&#40;&#40;&#40;kinisis_1c + kinisis_1e + &#40;kinisis_1c / kinisis_1b&#41;* kinisis_1a&#41; * &#40;1-fpa&#41;*1.005&#41; + 
                    &#40;&#40;100c + 100e + &#40;100c / 100b&#41;* 100a&#41; * &#40;1-fpa&#41;*1.005&#41; + 
                    &#40;&#40;super_1c  + super_1e + &#40;super_1c / super_1b&#41;* super_1a&#41; * &#40;1-fpa&#41;*1.005&#41; + 
                    &#40;&#40;95_1c + 95_1e + &#40;95_1c / 95_1b&#41;* 95_1a&#41; * &#40;1-fpa&#41;*1.005&#41; + 
                    &#40;&#40;95_2c + 95_2e + &#40;95_2c / 95_2b&#41;*  95_2a&#41; * &#40;1-fpa&#41;*1.005&#41; + 
                    &#40;&#40;super_2c + super_2e + &#40;super_2c / super_2b&#41;* super_2a&#41; * &#40;1-fpa&#41;*1.005&#41; + 
                    &#40;&#40;kinisis_2c + kinisis_2e + &#40;kinisis_2c / kinisis_2b&#41;*  kinisis_2a&#41; * &#40;1-fpa&#41;*1.005&#41;&#41; totalSum 
                FROM kiniseis 
            WHERE `kdate` BETWEEN ? AND ? 
            '; 
        $stmt = mysqli_prepare&#40;$con, $query&#41;; 
        mysqli_stmt_bind_param&#40;$stmt, 'ss', $date1, $date2&#41;; 
        mysqli_execute&#40;$stmt&#41;; 
        mysqli_bind_result&#40;$stmt, $mysqlSum&#41;; 
        mysqli_stmt_fetch&#40;$stmt&#41;; 
        mysqli_stmt_close&#40;$stmt&#41;; 
     
        //Show table data 
        $query = ' 
            SELECT 
                &#40;&#40;kinisis_1c + kinisis_1e + &#40;kinisis_1c / kinisis_1b&#41;* kinisis_1a&#41; * &#40;1-fpa&#41;*1.005&#41;, 
                &#40;&#40;100c + 100e + &#40;100c / 100b&#41;* 100a&#41; * &#40;1-fpa&#41;*1.005&#41;, 
                &#40;&#40;super_1c  + super_1e + &#40;super_1c / super_1b&#41;* super_1a&#41; * &#40;1-fpa&#41;*1.005&#41;, 
                &#40;&#40;95_1c + 95_1e + &#40;95_1c / 95_1b&#41;* 95_1a&#41; * &#40;1-fpa&#41;*1.005&#41;, 
                &#40;&#40;95_2c + 95_2e + &#40;95_2c / 95_2b&#41;*  95_2a&#41; * &#40;1-fpa&#41;*1.005&#41;, 
                &#40;&#40;super_2c + super_2e + &#40;super_2c / super_2b&#41;* super_2a&#41; * &#40;1-fpa&#41;*1.005&#41;, 
                &#40;&#40;kinisis_2c + kinisis_2e + &#40;kinisis_2c / kinisis_2b&#41;*  kinisis_2a&#41; * &#40;1-fpa&#41;*1.005&#41;, 
                kdate 
            FROM kiniseis 
            WHERE `kdate` BETWEEN ? AND ? 
            '; 
        $stmt = mysqli_prepare&#40;$con, $query&#41;; 
        mysqli_stmt_bind_param&#40;$stmt, 'ss', $date1, $date2&#41;; 
        mysqli_execute&#40;$stmt&#41;; 
        mysqli_bind_result&#40;$stmt, $calc1, $calc2, $calc3, $calc4, $calc5, $calc6, $calc7, $kdate&#41;; 
        $i = 0; 
        $phpSum = 0; 
        print &#40;"Printing table data and column sums as calculated by php\n"&#41;; 
        printf&#40;"%5s %15s %15s %15s %15s %15s %15s %15s %19s\n", 
                '#', 
                'calc1', 
                'calc2', 
                'calc3', 
                'calc4', 
                'calc5', 
                'calc6', 
                'calc7', 
                'kdate'&#41;; 
        print &#40;str_repeat&#40;'-',137&#41;."\n"&#41;; 
        $colSum1 = $colSum2 = $colSum3 = $colSum4 = $colSum5 = $colSum6 = $colSum7 = 0; 
        while &#40;mysqli_stmt_fetch&#40;$stmt&#41;&#41; 
        &#123; 
            ++$i; 
            $colSum1 += $calc1; 
            $colSum2 += $calc2; 
            $colSum3 += $calc3; 
            $colSum4 += $calc4; 
            $colSum5 += $calc5; 
            $colSum6 += $calc6; 
            $colSum7 += $calc7; 
            printf&#40;"%5d %15s %15s %15s %15s %15s %15s %15s %12s\n", 
                    $i, 
                    number_format&#40;$calc1,2&#41;, 
                    number_format&#40;$calc2,2&#41;, 
                    number_format&#40;$calc3,2&#41;, 
                    number_format&#40;$calc4,2&#41;, 
                    number_format&#40;$calc5,2&#41;, 
                    number_format&#40;$calc6,2&#41;, 
                    number_format&#40;$calc7,2&#41;, 
                    $kdate&#41;; 
        &#125; 
        mysqli_stmt_close&#40;$stmt&#41;; 
        print &#40;str_repeat&#40;'-',137&#41;."\n"&#41;; 
        printf&#40;"%5s %15s %15s %15s %15s %15s %15s %15s\n", 
                'SUM =', 
                number_format&#40;$colSum1,2&#41;, 
                number_format&#40;$colSum2,2&#41;, 
                number_format&#40;$colSum3,2&#41;, 
                number_format&#40;$colSum4,2&#41;, 
                number_format&#40;$colSum5,2&#41;, 
                number_format&#40;$colSum6,2&#41;, 
                number_format&#40;$colSum7,2&#41;&#41;; 
        print &#40;str_repeat&#40;'-',117&#41;."\n"&#41;; 
    &#125; 

    //Calculate column sums using mysql and total sum using PHP 
    $query = ' 
        SELECT 
            SUM&#40;&#40;kinisis_1c + kinisis_1e + &#40;kinisis_1c / kinisis_1b&#41;* kinisis_1a&#41; * &#40;1-fpa&#41;*1.005&#41; sum1, 
            SUM&#40;&#40;100c + 100e + &#40;100c / 100b&#41;* 100a&#41; * &#40;1-fpa&#41;*1.005&#41; sum2, 
            SUM&#40;&#40;super_1c  + super_1e + &#40;super_1c / super_1b&#41;* super_1a&#41; * &#40;1-fpa&#41;*1.005&#41; sum3, 
            SUM&#40;&#40;95_1c + 95_1e + &#40;95_1c / 95_1b&#41;* 95_1a&#41; * &#40;1-fpa&#41;*1.005&#41; sum4, 
            SUM&#40;&#40;95_2c + 95_2e + &#40;95_2c / 95_2b&#41;*  95_2a&#41; * &#40;1-fpa&#41;*1.005&#41; sum5, 
            SUM&#40;&#40;super_2c + super_2e + &#40;super_2c / super_2b&#41;* super_2a&#41; * &#40;1-fpa&#41;*1.005&#41; sum6, 
            SUM&#40;&#40;kinisis_2c + kinisis_2e + &#40;kinisis_2c / kinisis_2b&#41;*  kinisis_2a&#41; * &#40;1-fpa&#41;*1.005&#41; sum7 
        FROM kiniseis 
        WHERE `kdate` BETWEEN ? AND ? 
        '; 
    $stmt = mysqli_prepare&#40;$con, $query&#41;; 
    mysqli_stmt_bind_param&#40;$stmt, 'ss', $date1, $date2&#41;; 
    mysqli_execute&#40;$stmt&#41;; 
    mysqli_bind_result&#40;$stmt, $sum1, $sum2, $sum3, $sum4, $sum5, $sum6, $sum7&#41;; 
    $i = 0; 
    $phpSum = 0; 
    print &#40;"\nPrinting column sums as calculated by mysql with total sums as calculated by both mysql and php\n"&#41;; 
    printf&#40;"%5s %15s %15s %15s %15s %15s %15s %15s %19s\n", 
            '#', 
            'sum1', 
            'sum2', 
            'sum3', 
            'sum4', 
            'sum5', 
            'sum6', 
            'sum7', 
            'rowSum'&#41;; 
    print &#40;str_repeat&#40;'-',137&#41;."\n"&#41;; 
    while &#40;mysqli_stmt_fetch&#40;$stmt&#41;&#41; 
    &#123; 
        ++$i; 
        $rowSum = $sum1 + $sum2 + $sum3 + $sum4 + $sum5 + $sum6 + $sum7; 
        $phpSum += $rowSum; 
        printf&#40;"%5d %15s %15s %15s %15s %15s %15s %15s %19s\n", 
                $i, 
                number_format&#40;$sum1,2&#41;, 
                number_format&#40;$sum2,2&#41;, 
                number_format&#40;$sum3,2&#41;, 
                number_format&#40;$sum4,2&#41;, 
                number_format&#40;$sum5,2&#41;, 
                number_format&#40;$sum6,2&#41;, 
                number_format&#40;$sum7,2&#41;, 
                number_format&#40;$rowSum,2&#41;&#41;; 
    &#125; 
    mysqli_stmt_close&#40;$stmt&#41;; 
    mysqli_close&#40;$con&#41;; 

    print &#40;str_repeat&#40;'-',137&#41;."\n"&#41;; 
    printf&#40;"%137s\n", 'MySql SUM&#40;&#41; = ' . number_format&#40;$rowSum, 2&#41;&#41;; 
    printf&#40;"%137s\n", 'PHP Sum     = ' . number_format&#40;$phpSum, 2&#41;&#41;; 
?> 
Φυσικά τα links άγνωστο μέχρι πότε θα ισχύουν, όποιος ενδιαφέρεται και προλάβει δοκιμάζει.

Ουφ, πολύ γράψιμο. Μια μπύρα είναι απαραίτητη. :pint:

nbc
Honorary Member
Δημοσιεύσεις: 526
Εγγραφή: 05 Σεπ 2009 20:12
Επικοινωνία:

Δημιουργια Συνάρτησης SUM

Δημοσίευση από nbc » 28 Ιουν 2010 21:11

Τι έκανε ο άνθρωπος... Respect!

ORB
Δημοσιεύσεις: 19
Εγγραφή: 16 Ιουν 2010 22:57

Δημιουργια Συνάρτησης SUM

Δημοσίευση από ORB » 28 Ιουν 2010 21:15

Λοιπον...

Χρησιμοποιησα αυτο το query

Κώδικας: Επιλογή όλων

$query_Totals_i = "SELECT &#40;kinisis_1c + kinisis_1e + &#40;&#40;kinisis_1c / kinisis_1b&#41; * kinisis_1a&#41;&#41; * &#40;1 - fpa&#41; * 1.005 AS kinisis_1,   &#40;100c+ 100e+ &#40;&#40;100c/ 100b&#41; * 100a&#41;&#41; * &#40;1 - fpa&#41; * 1.005 AS `100ara`,   &#40;super_1c + super_1e + &#40;&#40;super_1c / super_1b&#41; * super_1a&#41;&#41; * &#40;1 - fpa&#41; * 1.005 AS super_1,   &#40;95_1c+ 95_1e+ &#40;&#40;95_1c/ 95_1b&#41; * 95_1a&#41;&#41; * &#40;1 - fpa&#41; * 1.005 AS `95_1`,   &#40;95_2c+ 95_2e+ &#40;&#40;95_2c/ 95_2b&#41; * 95_2a&#41;&#41; * &#40;1 - fpa&#41; * 1.005 AS `95_2`,   &#40;super_2c + super_2e + &#40;&#40;super_2c / super_2b&#41; * super_2a&#41;&#41; * &#40;1 - fpa&#41; * 1.005 AS super_2,   &#40;kinisis_2c + kinisis_2e + &#40;&#40;kinisis_2c / kinisis_2b&#41; * kinisis_2a&#41;&#41; * &#40;1 - fpa&#41; * 1.005 AS kinisis_2 FROM kiniseis WHERE `date` BETWEEN '$_GET&#91;date1&#93;' AND '$_GET&#91;date2&#93;'";

$Totals_i = mysql_query&#40;$query_Totals_i, $gas_connection&#41; or die&#40;mysql_error&#40;&#41;&#41;;
$row_Totals_i = mysql_fetch_assoc&#40;$Totals_i&#41;;
$totalRows_Totals_i = mysql_num_rows&#40;$Totals_i&#41;;
Και το παρακατω script για να υπολογισει τα αθροισματα για καθε ψευδο-στηλη.(πχ την πρωτη στηλη αθροισματων i1)

Κώδικας: Επιλογή όλων

$i1 = array&#40;$row_Totals_i&#91;'kinisis_1'&#93;&#41;;
echo "" . array_sum&#40;$i1&#41; . "\n";
Αλλα τρωω πορτα , μου υπολογιζει μονο το 1 record αντι να διαβασει και ολα τα υπολοιπα μεταξυ των ημερομηνιων που το δινω...

Οταν η array() εχει μεσα απλα αριθμους ειναι γελοίο , αλλα τωρα που ολα ειναι δυναμικα δε ξερω που παν τα 4.

Εχει καποιος καποια ιδεα?

ORB
Δημοσιεύσεις: 19
Εγγραφή: 16 Ιουν 2010 22:57

Δημιουργια Συνάρτησης SUM

Δημοσίευση από ORB » 28 Ιουν 2010 21:54

Oυπς δε σε προλαβα dva_dev :hammer:

Σε ευχαριστω καταρχας για το κοπο σου.
Οσον αφορα την αποκλιση ηθελα να επισημανω κατι.

Αυτο το ειχα ανακαλυψει καταλαθος, οταν εβαζα τα ημερησια αθροισματα στο excel και μετα υπολογιζα το τελικο.

Εκανα copy paste 57 εγγραφες απο 3-10-2006 μεχρι 5-12-2006 , και ειδα στο excel αθροισμα 296,000.76 (οπως και manually με το κομπιουτερακι)
Η mysql με την php μου δίνουν 295,697.14.
Τα πεδία τα έχω ολα double πλεον.

Τωρα μολις δοκιμασα απο 3-10-2006 μεχρι 15-10-2006 , και excel και php-mysql συμφωνουνε απολυτα.

Αρα κατι παιζει εδω περα.

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Δημιουργια Συνάρτησης SUM

Δημοσίευση από dva_dev » 28 Ιουν 2010 23:37

Ισως αν εμφανίσεις 10 δεκαδικά να συμφωνήσει το excel με όλους τους άλλους...
Οπως καταλαβαίνω το πρόβλημα σου είναι στο business κομμάτι που πας να υλοποιήσεις. Κάτι σου έχει ξεφύγει και δεν ξέρεις αν πρέπει να κάνεις στρογγυλοποιήσεις και πότε, ή όχι. Σε αυτό δεν μπορώ να σε βοηθήσω. Αν όμως χρειάζεται να κάνεις κάτι πρέπει να διευκρινίσεις ακριβώς τι είναι αυτό. Αποκοπή; Στρογγυλοποίηση; Με τι μέθοδο; Μήπως αυτό που θέλεις είναι να κάνεις πράξεις με αποτελέσματα σταθερής ακρίβειας (οπότε και στη mysql πας σε decimal);

Η διαφορά που βλέπεις στο excel με οτιδήποτε άλλο προκύπτει από το ότι κάνεις πράξεις με στρογγυλοποιημένα αποτελέσματα, ενώ στην php και mysql χρησιμοποιείς όλη τη δυνατή ακρίβεια. Χρησιμοποιείς διαφορετικές μεθόδους για να κάνεις τις πράξεις και να δεις τι βγάζει το τελικό σύνολο.

Υπάρχουν αρκετές functions που κάνουν τη "δημιουργική λογιστική" παιχνιδάκι. Διαλέγεις και παίρνεις:
http://php.net/manual/en/function.round.php
http://www.electrictoolbox.com/php-round-numbers/
http://www.php.net/manual/en/ref.math.php
http://www.php.net/manual/en/book.math.php

[edit]
Ενα αντίστοιχο χαρακτηριστικό πρόβλημα είναι το θέμα των ιστοτιμιών.
1€ = 341δρχ.
1000€ = ?

Αν πας σε μία τράπεζα για να πάρεις 1000€ πόσες δραχμές πρέπει να δώσεις συνολικά;
Αν πας σε 1000 τράπεζες για να πάρεις από 1€ κάθε φορά πόσες δραχμές πρέπει να δώσεις συνολικά;
[/edit]

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Δημιουργια Συνάρτησης SUM

Δημοσίευση από Apostolis_38 » 28 Ιουν 2010 23:57

dva_dev έγραψε:και δεν ξέρεις αν πρέπει να κάνεις στρογγυλοποιήσεις και πότε, ή όχι.
Φίλε ORB, αν θέλεις την άποψη μου, αν πρόκειται για οποιαδήποτε εφαρμογή η οποία δεν μπλεκει με "επίσημα χαρτιά" (εφορίες, φορολογικούς μηχανισμούς) κ.λ.π. μην κάθεσαι να μπλέξεις.
Υλοποίησε μια μέθοδο στρογγυλοποίησης και απλώς εξήγησε στον χειριστή/πελάτη οτι υπάρχει αυτό το φαινόμενο.
Απ' ότι είδα κάνεις πολλές πράξεις κι αν τυχόν μεγαλώσει το σύνολο των πράξεων που εκτελούνται είναι πολύ πιθανό να σου ξεφύγει και και να τραβιέσαι μερόνυχτα να βρείς τι φταίει.
Δεν νομίζω οτι μισό ευρώ είναι τόσο μεγάλο θέμα για μια απλή εφαρμογή.

dva_dev: respect κι από μένα

ORB
Δημοσιεύσεις: 19
Εγγραφή: 16 Ιουν 2010 22:57

Δημιουργια Συνάρτησης SUM

Δημοσίευση από ORB » 30 Ιουν 2010 02:11

Apostolis_38 έγραψε:
dva_dev έγραψε:και δεν ξέρεις αν πρέπει να κάνεις στρογγυλοποιήσεις και πότε, ή όχι.
Φίλε ORB, αν θέλεις την άποψη μου, αν πρόκειται για οποιαδήποτε εφαρμογή η οποία δεν μπλεκει με "επίσημα χαρτιά" (εφορίες, φορολογικούς μηχανισμούς) κ.λ.π. μην κάθεσαι να μπλέξεις.
Υλοποίησε μια μέθοδο στρογγυλοποίησης και απλώς εξήγησε στον χειριστή/πελάτη οτι υπάρχει αυτό το φαινόμενο.
Απ' ότι είδα κάνεις πολλές πράξεις κι αν τυχόν μεγαλώσει το σύνολο των πράξεων που εκτελούνται είναι πολύ πιθανό να σου ξεφύγει και και να τραβιέσαι μερόνυχτα να βρείς τι φταίει.
Δεν νομίζω οτι μισό ευρώ είναι τόσο μεγάλο θέμα για μια απλή εφαρμογή.

dva_dev: respect κι από μένα
Φιλε μου αν ηταν μισο ευρο εννοειτε δε θα εκανα λογο...υπαρχει διαφορά περι τα 120/μηνα δυστηχως...
Οχι δεν μπλεκει με επισημα χαρτια, ειναι απλα για πιστοποιηση , εσοδων εξοδων, ενος φιλου μου.

Ηρθα σε επαφη με εναν author του sitepoint, υποτιθεται ειναι guru στη mysql και sql consultant, μου ζητησε το create statement , και insert για να δει τι συμβαινει.

Αληθεια εχει αντιμετοπισει κανεις παρομοια περιπτωση? Εμενα ηταν η πρωτη φορα.

ORB
Δημοσιεύσεις: 19
Εγγραφή: 16 Ιουν 2010 22:57

Δημιουργια Συνάρτησης SUM

Δημοσίευση από ORB » 30 Ιουν 2010 02:15

dva_dev έγραψε:Ισως αν εμφανίσεις 10 δεκαδικά να συμφωνήσει το excel με όλους τους άλλους...
Οπως καταλαβαίνω το πρόβλημα σου είναι στο business κομμάτι που πας να υλοποιήσεις. Κάτι σου έχει ξεφύγει και δεν ξέρεις αν πρέπει να κάνεις στρογγυλοποιήσεις και πότε, ή όχι. Σε αυτό δεν μπορώ να σε βοηθήσω. Αν όμως χρειάζεται να κάνεις κάτι πρέπει να διευκρινίσεις ακριβώς τι είναι αυτό. Αποκοπή; Στρογγυλοποίηση; Με τι μέθοδο; Μήπως αυτό που θέλεις είναι να κάνεις πράξεις με αποτελέσματα σταθερής ακρίβειας (οπότε και στη mysql πας σε decimal);

Η διαφορά που βλέπεις στο excel με οτιδήποτε άλλο προκύπτει από το ότι κάνεις πράξεις με στρογγυλοποιημένα αποτελέσματα, ενώ στην php και mysql χρησιμοποιείς όλη τη δυνατή ακρίβεια. Χρησιμοποιείς διαφορετικές μεθόδους για να κάνεις τις πράξεις και να δεις τι βγάζει το τελικό σύνολο.

Υπάρχουν αρκετές functions που κάνουν τη "δημιουργική λογιστική" παιχνιδάκι. Διαλέγεις και παίρνεις:
http://php.net/manual/en/function.round.php
http://www.electrictoolbox.com/php-round-numbers/
http://www.php.net/manual/en/ref.math.php
http://www.php.net/manual/en/book.math.php

[edit]
Ενα αντίστοιχο χαρακτηριστικό πρόβλημα είναι το θέμα των ιστοτιμιών.
1€ = 341δρχ.
1000€ = ?

Αν πας σε μία τράπεζα για να πάρεις 1000€ πόσες δραχμές πρέπει να δώσεις συνολικά;
Αν πας σε 1000 τράπεζες για να πάρεις από 1€ κάθε φορά πόσες δραχμές πρέπει να δώσεις συνολικά;
[/edit]
Bασικα οσον αφορα τη mysql δε θελω να κανω καθολου στρογυλοποιησεις.
Στρογυλλοποιηση κανω μονο στα τελικα αποτελεσματα οπου εκει δε με απασχολει φυσικα το αν το 454,545.38 γινει 454,545.40 .

Παντως απο ερευνα παρατηρησα οτι και αλλοι webmaster του εξωτερικου εχουν βρεθει με το ιδιο προβλημα , αλλα σε shopping cart , κατα την διαδικασια της προσθεσης.

Σκεφτηκα να προσθεσω ενα ακομα column οπου κατα το insert statement που θα περναει αυτοματα το αποτελεσμα της πηλικο διαιρεσης * αριθμο , ωστε να απλουστευτει το sum()
ωστε η τελευταια να μη κανει στρογγυλοποιησεις, αλλα θα δω τι θα μου πει και ο αλλος απο το sitepoint.


Σε ευχαριστω παρα παρα πολυ παντως :)

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Δημιουργια Συνάρτησης SUM

Δημοσίευση από dva_dev » 30 Ιουν 2010 10:48

Τα super_1a, super_1b, super_1c, super_1b τι είναι, τι σημαίνουν;
Το (super_1c + super_1e + (super_1c / super_1b)* super_1a) * (1-fpa)*1.005 τι είναι; Πρέπει να γίνει στρογγυλοποίηση σε αυτό το πράγμα και αν πρέπει στα πόσα δεκαδικά;
Αν αυτό το πράγμα είναι χρήματα από κάποια πώληση ενός είδους προϊόντος (π.χ. βενζίνη super) μια συγκεκριμένη ημέρα, τότε ίσως αυτό το αποτέλεσμα πρέπει να πάει στα 2 δεκαδικά με κάποια από τις διαθέσιμες μεθόδους στρογγυλοποίησης, πριν συμμετέχει σε οποιοδήποτε άλλο άθροισμα. Αυτό νομίζω πως μπορεί να στο πει μάλλον ο φίλος σου που είναι στο επάγγελμα και ξέρει το business κομμάτι.
(Αντίστοιχα φυσικά και για τα υπόλοιπα 6).

Αυτό εννοώ όταν λέω ότι το πρόβλημα σου είναι στο business κομμάτι που πας να υλοποιήσεις.

ORB
Δημοσιεύσεις: 19
Εγγραφή: 16 Ιουν 2010 22:57

Δημιουργια Συνάρτησης SUM

Δημοσίευση από ORB » 30 Ιουν 2010 22:11

dva_dev έγραψε:Τα super_1a, super_1b, super_1c, super_1b τι είναι, τι σημαίνουν;
Το (super_1c + super_1e + (super_1c / super_1b)* super_1a) * (1-fpa)*1.005 τι είναι; Πρέπει να γίνει στρογγυλοποίηση σε αυτό το πράγμα και αν πρέπει στα πόσα δεκαδικά;
Αν αυτό το πράγμα είναι χρήματα από κάποια πώληση ενός είδους προϊόντος (π.χ. βενζίνη super) μια συγκεκριμένη ημέρα, τότε ίσως αυτό το αποτέλεσμα πρέπει να πάει στα 2 δεκαδικά με κάποια από τις διαθέσιμες μεθόδους στρογγυλοποίησης, πριν συμμετέχει σε οποιοδήποτε άλλο άθροισμα. Αυτό νομίζω πως μπορεί να στο πει μάλλον ο φίλος σου που είναι στο επάγγελμα και ξέρει το business κομμάτι.
(Αντίστοιχα φυσικά και για τα υπόλοιπα 6).

Αυτό εννοώ όταν λέω ότι το πρόβλημα σου είναι στο business κομμάτι που πας να υλοποιήσεις.
Nαι ειναι για ενα βενζιναδικο που θελει ενας φιλος να κανει επαληθευση οικονομικων.
Ολα τα πεδια ειναι ακεραιοι, χωρις δεκαδικα .

Βρηκα αυτο απο microsoft , πολυ διαφωτιστικο και περιγραφει αυτο ακριβως το προβλημα που εχω, επειδη χρησημοποιω πηλικο διαίρεσης μεσα σε sum formula.
http://support.microsoft.com/kb/281341

Συνεπως μπορω να κανω 2 πραγματα:
H να προσθεσω αλλο ενα πεδιο στη βαση οπου κατα το ιnsert record, να υπολογιζει το πηλικο της διαρεσης με τον αριθμο πχ (super_1c / super_1b)* super_1a) ,ωστε η sum να κανει μονο προσθέσεις....
Η να βρω ενα τροπο να κανω implementation το work arround της microsoft στη mysql.

Aπο ότι ειδα το μονο που μπορω να κανω ειναι να βγαλω το sum απο το recordset pου εχω δημιουργησει , να δημιουργησω ενα query χωρις τη sum, και στη συνεχεια στο καθε κελι να πω στη php , να κανει sum τη μεταβλητη, απο date1 μεχρι date2.

Αποψεις?

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Δημιουργια Συνάρτησης SUM

Δημοσίευση από dva_dev » 01 Ιούλ 2010 00:03

Εννοούσα τι είναι το κάθε πεδίο της εγγραφής σου. Το super_1a ας πούμε, τι είναι; Λίτρα βενζίνης ή το κόστος της βενζίνης ανά λίτρο;
Η παράσταση (super_1c + super_1e + (super_1c / super_1b)* super_1a) * (1-fpa)*1.005 τι είναι αυτό που δίνει σαν αποτέλεσμα, κάποιο ποσό σε χρήματα ή ποσό σε λίτρα; Το δεύτερο μου φαίνεται δύσκολο μιας και μπλέκεται μέσα και πεδίο με όνομα fpa, εκτός και αν είναι παραπλανητικό το όνομα.

Επίσης θα το απέκλεια να είναι όλα τα πεδία ακέραιοι γιατί ακόμα και λίτρα να είναι έχεις δεκαδικά (χιλιοστά μάλλον, τα ml). Αλλά σε κάθε περίπτωση δεν μπορείς να πολλαπλασιάζεις λίτρα μόνο, να τους βάζεις και φπα και ένα 1.005 (το οποίο δεν μου δίνει κάποιο στοιχείο για το τι θα μπορούσε να είναι) για να πάρεις τελικώς έσοδα. Τι θα κάνεις, στο τέλος της χρονιάς θα πάρεις 2 μπιτόνια βενζίνη super και 5 πετρέλαιο κίνησης, και θα τα καταθέσεις στην εφορία για να πληρώσεις το φπα; Κάπου μέσα στην όλη πράξη πρέπει να μπλέκονται και χρήματα, και κρίνοντας από τις τιμές στα βενζινάδικα πρέπει να έχεις τουλάχιστον 3 δεκαδικά ακρίβεια στις ενδιάμεσες πράξεις και 2 στο τελικό αποτέλεσμα.
Τώρα που ακριβώς είναι που θα μεταβείς από τα 3 δεκαδικά στα 2, όταν δουλέψω σε βενζινάδικο θα στο πω.

Μια μαντεψιά μόνο που μπορώ να κάνω είναι ότι η στρογγυλοποίηση (αν πρόκειται για στρογγυλοποίηση και όχι για αποκοπή) που θέλεις θα γίνει μέσα στη sum στο στύλ:

Κώδικας: Επιλογή όλων

SUM&#40;ROUND&#40;&#40;super_1c + super_1e + &#40;super_1c / super_1b&#41;* super_1a&#41; * &#40;1-fpa&#41;*1.005, 2&#41;&#41;
αντί του

Κώδικας: Επιλογή όλων

SUM&#40;&#40;super_1c + super_1e + &#40;super_1c / super_1b&#41;* super_1a&#41; * &#40;1-fpa&#41;*1.005&#41;
Αν τώρα είναι να κάνεις τις στρογγυλοποιήσεις στην php τότε πρέπει να παίξεις με τη round και όχι με τη number_format. Αυτή είναι μόνο για την εμφάνιση του αποτελέσματος (και καλό είναι στην αρχή μέχρι να σιγουρευτείς ότι οι πράξεις σου είναι σωστές να εμφανίζεις ένα δεκαδικό τουλάχιστον παραπάνω από αυτά που χρειάζεσαι στις πράξεις σου τσεκάροντας παράλληλα ότι το τελευταίο δεκαδικό είναι μηδέν.

Π.χ. αν στην αμόλυβδη/λίτρο έχεις κόστος (στη mysql ή στην php εκεί που κάνεις τις πράξεις) 1,499 να εμφανίζεις στην php 4 δεκαδικά. Να δείχνεις 1,4990. Και αφού σιγουρευτείς ότι όλα τα αποτελέσματα είναι σωστά το αφαιρείς το επιπλέον δεκαδικό.

Τα bugs της microsoft αφορούν τα δικά της προϊόντα και το συγκεκριμένο αναφέρει
APPLIES TO
Microsoft SQL Server 7.0 Standard Edition
Microsoft SQL Server 2000 Standard Edition
Αν ισχύει και στη mysql θα πρέπει να το τσεκάρεις και δεν είναι και σίγουρο ότι αν ισχύει ένα αντίστοιχο work arround θα σου λύσει το πρόβλημα στη mysql.

ORB
Δημοσιεύσεις: 19
Εγγραφή: 16 Ιουν 2010 22:57

Δημιουργια Συνάρτησης SUM

Δημοσίευση από ORB » 15 Ιούλ 2010 17:34

@dva_dev

Ok τελικα ειναι κατι σαν αναποφευχτο bug της sum οταν εμπεριεχει 1+.....ν πηλίκα μεσα στη formula της.
Προσθεσα αλλα 7 πεδια στη βάση τα οποια κατα το insert record , κρατανε το αποτελεσμα πχ (α/β)*γ , ωστε η sum να προσθετει απλα αριθμους , και εν συνεχεια το προβλημα λυθηκε , δεν υφιστανται πλεον απωλειες ακριβειας.

Οποτε προς γνωση ολων οταν χρησιμοποιητε τη sum αποφυγετε τα πηλικα μεσα της οσο μπορειτε :)

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Δημιουργια Συνάρτησης SUM

Δημοσίευση από dva_dev » 15 Ιούλ 2010 19:45

Στα νέα πεδία που πρόσθεσες και κρατάς τα αποτελέσματα (super_1c + super_1e + (super_1c / super_1b)* super_1a) * (1-fpa)*1.005, τα κρατάς όλα τα δεκαδικά ή κάνεις στρογγυλοποίηση στα 2 δεκαδικά τελικά;

ORB
Δημοσιεύσεις: 19
Εγγραφή: 16 Ιουν 2010 22:57

Δημιουργια Συνάρτησης SUM

Δημοσίευση από ORB » 16 Ιούλ 2010 03:29

Στα πεδια που προσθεσα υπολογιζω μονο το πχ (super_1c / super_1b)* super_1a κτλ, και τα εχω βαλει DECIMAL(10,4)
Κραταω μονο 4 δεκαδικα

Απάντηση

Επιστροφή στο “PHP Προγραμματισμός”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 2 επισκέπτες