1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Trouble updating particular Records

Discussion in 'MySQL' started by Landslyde, Sep 12, 2015.

  1. #1
    Hi Forum:

    I have a db that therapists use to track their patients. The History table keeps track of the payments, attendance, and a few other details. When the therapist pulls up the post payment page, he selects the Group ID and loads a dropdown box with group member names. Then, as they pay, using the dropdown box to load their information, he posts their payments. This action updates the payment history for each patient indiviaually. It also updates the attendance fields ( attend = "Y" and attend_date = CURDATE() ). By default , the attend field is "N".
    My problem is that I have no idea how to extract the patients from the History table that were not present, leaving the attend field to its default while inserting the CURDATE(). I was thinking I cld pull up the last record for each patient in any particular Group and check the last-entered attendance date against CURDATE(), then insert the CURDATE() if it didn't match. And while I think this might be the ticket, I'm really new to MySQL and am not sure how to implement such an idea. I'm not looking for anyone to write my code for me, but I'd really appreciate a little guidance and insight on this. Thanks.
    Here is the History schema:

    CREATE TABLE `history` (
    `historyid` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `amount` float NOT NULL,
    `subsidy` char(1) NOT NULL,
    `last_payment` date NOT NULL,
    `amount_paid` float NOT NULL,
    `balance` float NOT NULL,
    `attend` char(1) NOT NULL DEFAULT 'N',
    `attend_date` date NOT NULL,
    `attendeeid` int(10) unsigned NOT NULL,
    `memberid` int(10) unsigned NOT NULL,
    PRIMARY KEY (`historyid`),
    KEY `attendeeid` (`attendeeid`),
    CONSTRAINT `history_ibfk_10` FOREIGN KEY (`attendeeid`) REFERENCES `attendees` (`attendeeid`) ON DELETE CASCADE ON UPDATE NO ACTION
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    I'm not sure what else I might need to provide. Please advise.
     
    Landslyde, Sep 12, 2015 IP
  2. Landslyde

    Landslyde Peon

    Messages:
    7
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    1
    #2
    Sometimes it just takes walking away from your work and catching a breath of fresh air. I solved my issue over my first cup of coffee. Here's my working solution:

    
    if($_POST['flush']) {
                            try {
                                $groupid = $_SESSION['groupid'];
                                $stmt = $db->prepare('SELECT historyid, amount, subsidy, last_payment, amount_paid, balance, 
                                                                        attend_date, h.memberid, a.groupid, a.attendeeid, h.attendeeid
                                                                FROM history AS h 
                                                                INNER JOIN attendees AS a ON a.attendeeid = h.attendeeid
                                                                WHERE a.groupid = :groupid
                                                                ORDER BY historyid DESC LIMIT 1');
                                $stmt->bindValue(':groupid', $groupid, PDO::PARAM_INT);
                                $stmt->execute();
                                $result = $stmt->fetchAll();
                               
                                foreach($result as $row ) { 
                                    $amount = $row[1];           
                                    $subsidy = $row[2];
                                    $last_pymt = $row[3];
                                    $amtpaid = $row[4];
                                    $balance = $row[5];                                                           
                                    $memid = $row[7];                               
                                    $attid = $row[9];
                                    if($row[6] <> date('Y-m-d')) {
                                        $stmt = $db->prepare('INSERT INTO history(amount, subsidy, last_payment, amount_paid, balance, 
                                                                        attend_date, attendeeid, memberid)
                                                                    VALUES(:amt, :sub, :lastpayment, :amt_paid, :bal, CURDATE(), 
                                                                        :attid, :memid)');
                                        $stmt->bindParam(':amt', $amount, PDO::PARAM_STR);
                                        $stmt->bindParam(':sub', $subsidy, PDO::PARAM_STR);       
                                        $stmt->bindParam(':lastpayment', $last_pymt, PDO::PARAM_STR);
                                        $stmt->bindParam(':amt_paid', $amtpaid, PDO::PARAM_STR);
                                        $stmt->bindParam(':bal', $balance, PDO::PARAM_STR);
                                        $stmt->bindParam(':attid', $attid, PDO::PARAM_STR);
                                        $stmt->bindParam(':memid', $memid, PDO::PARAM_STR);
                                        $stmt->execute();                           
                                    }                       
                                }
                            } catch (PDOException $ex) { ... }
    
    Code (markup):
     
    Landslyde, Sep 13, 2015 IP
  3. Landslyde

    Landslyde Peon

    Messages:
    7
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    1
    #3
    Like I said, I'm new to MySQL. Although my above code works, it only inserts on the first record it finds that matches the groupid number. How can I make it cycle through the entire table and INSERT the new record as needed? I'm beginning to think I have a whole lot wrong here.
     
    Landslyde, Sep 13, 2015 IP
  4. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #4
    Instead of doing a fetchAll() and looping the resulting array, just do a while ($row = $stmt->fetch()) { and do the inserts here } should work (it will loop through all results, and based on the results, it will update for each result it finds.
     
    PoPSiCLe, Sep 13, 2015 IP
  5. Landslyde

    Landslyde Peon

    Messages:
    7
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    1
    #5
    PoPSiCLe:

    I made the change you suggested, but it only writes one insertion then stops before finishing the other needed insertions. Did I do it wrong?
    
    if($_POST['flush']) {
                            try {
                                $groupid = $_SESSION['groupid'];
                                $stmt = $db->prepare('SELECT historyid, amount, subsidy, last_payment, amount_paid, balance,
                                                                        attend_date, h.memberid, a.groupid, a.attendeeid, h.attendeeid
                                                                FROM history AS h
                                                                INNER JOIN attendees AS a ON a.attendeeid = h.attendeeid
                                                                WHERE a.groupid = :groupid
                                                                ORDER BY historyid DESC LIMIT 1');
                                $stmt->bindValue(':groupid', $groupid, PDO::PARAM_INT);
                                $stmt->execute();
                         
                                while($row = $stmt->fetch()) {
                                    $amount = $row[1];     
                                    $subsidy = $row[2];
                                    $last_pymt = $row[3];
                                    $amtpaid = $row[4];
                                    $balance = $row[5];                                                     
                                    $memid = $row[7];                         
                                    $attid = $row[9];
                                    if($row[6] != date('Y-m-d')) {
                                        $stmt = $db->prepare('INSERT INTO history(amount, subsidy, last_payment, amount_paid, balance,
                                                                        attend_date, attendeeid, memberid)
                                                                    VALUES(:amt, :sub, :lastpayment, :amt_paid, :bal, CURDATE(),
                                                                        :attid, :memid)');
                                        $stmt->bindParam(':amt', $amount, PDO::PARAM_STR);
                                        $stmt->bindParam(':sub', $subsidy, PDO::PARAM_STR); 
                                        $stmt->bindParam(':lastpayment', $last_pymt, PDO::PARAM_STR);
                                        $stmt->bindParam(':amt_paid', $amtpaid, PDO::PARAM_STR);
                                        $stmt->bindParam(':bal', $balance, PDO::PARAM_STR);
                                        $stmt->bindParam(':attid', $attid, PDO::PARAM_STR);
                                        $stmt->bindParam(':memid', $memid, PDO::PARAM_STR);
                                        $stmt->execute();                     
                                    }                 
                                }
                            } catch (PDOException $ex) { ... }
    
    Code (markup):
    Through analysis using Adminer, I see that the problem for the single retrieval is the:
    ORDER BY historyid DESC LIMIT 1
    Code (markup):
    Using that only allows the retrieval of the last record located in the History table. How do I change this so that it retrieves the last record for each attendee with the same groupid, then compares the date
    if($row[6] != date('Y-m-d'))
    Code (markup):
    to see if an insertion is needed?
     
    Last edited: Sep 14, 2015
    Landslyde, Sep 14, 2015 IP
  6. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #6
    You just remove the limit 1 - if the rest of the query is correct it should do what you want. But if you already know the date, why don't you match against that in the query as well?
     
    PoPSiCLe, Sep 14, 2015 IP
  7. Landslyde

    Landslyde Peon

    Messages:
    7
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    1
    #7
    I cldn't match the date against the query because the History table tracks payment and attendance History for the attendees. There will be many prior payment and attendance records that wldn't match the CURDATE() and wld be falsely updated. As for your other suggestion of removing the limit 1, doing that retrieves every History record in the table for the groupID in question.
    What I need this query to do is pull out the last-entered record for each attendee so I can test them to see if they need to be sent on to the INSERT statement or not.
     
    Last edited: Sep 14, 2015
    Landslyde, Sep 14, 2015 IP