Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3353956
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T02:12:50+00:00 2026-05-18T02:12:50+00:00

I have a table called pettycash CREATE TABLE `pettycash` ( `pc_id` int(7) NOT NULL

  • 0

I have a table called pettycash

CREATE TABLE `pettycash` (
  `pc_id` int(7) NOT NULL AUTO_INCREMENT,
  `pc_date` date NOT NULL,
  `pc_in` double(13,2) DEFAULT '0.00',
  `pc_out` double(13,2) DEFAULT '0.00',
  `pc_bal` double(13,2) DEFAULT '0.00',
  `pc_ref` varchar(95) DEFAULT NULL,
  `pc_user` varchar(65) DEFAULT NULL,
  `pc_terminal` varchar(128) DEFAULT NULL,
  `pc_void` tinyint(1) DEFAULT '0',
   PRIMARY KEY (`pc_id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

This table stores data about the petty cash management,but i have a simple problem of updating the balance as at a particular date. Each time i insert i run the following query:

UPDATE pettycash a SET pc_bal=SUM(pc_in-pc_out) WHERE pc_id=" & newID 

but the problem comes when someone comes to post transactions for a previous date like yesterday. the above query will only update one row and the other rows of a more current date will have wrong balance values. Is there a query or a Stored Procedure that will update the whole table getting the correct balance for each date?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T02:12:51+00:00Added an answer on May 18, 2026 at 2:12 am

    Triggers are probably want you want. However, getting this to work properly and efficiently will be ugly. It’s probably better not to store the balance in each row if you’re going to be inserting rows at earlier dates all that frequently; instead, use queries or views to find the balance. To find the balance on a particular date, join it with the rows for earlier dates and sum the net deposit, grouping by the current transaction ID:

    CREATE VIEW pettybalance
      AS SELECT SUM(older.pc_in - older.pc_out) AS balance, 
                current.pc_id AS pc_id,  -- foreign key
                current.pc_date AS `date`
           FROM pettycash AS current
             JOIN pettycash AS older
               ON current.pc_date > older.pc_date 
                  OR (current.pc_date = older.pc_date AND current.pc_id >= older.pc_id)
           GROUP BY current.pc_id
    ;
    

    I also restrict older.pc_id to be less than current.pc_id in order to fix an ambiguity relating to the schema and the balance calculation. Since the pc_date isn’t unique, you could have multiple transactions for a given date. If that’s the case, what should the balance be for each transaction? Here we assume that a transaction with a larger ID comes after a transaction with a smaller ID but that has the same date. More formally, we use the ordering

    a > b ⇔ a.pc_date > b.pc_date ∨ (a.pc_date = b.pc_date ∧ a.pc_id > b.pc_id)

    Note that in the view, we use a ≥ order based on >:

    a ≥ b ⇔ a.pc_date > b.pc_date ∨ (a.pc_date = b.pc_date ∧ a.pc_id ≥ b.pc_id)

    After trying to get triggers to work properly, I’m going to recommend not even trying. Due to internal table or row locks when inserting/updating, you have to move the balance column to a new table, though this isn’t too onerous (rename pettycash to pettytransactions, create a new pettybalance (balance, pc_id) table, and create a view named pettycash than joins pettytransactions and pettybalance on pc_id). The main problem is that trigger bodies execute once for each row created or updated, which will cause them to be incredibly inefficient. An alternative would be to create a stored procedure to update columns, which you can call after inserting or updating. A procedure is more performant when getting balances than a view, but more brittle as it’s up to programmers to update balances, rather than letting the database handle it. Using a view is the cleaner design.

    DROP PROCEDURE IF EXISTS update_balance;
    delimiter ;;
    CREATE PROCEDURE update_balance (since DATETIME)
    BEGIN
        DECLARE sincebal DECIMAL(10,2);
        SET sincebal = (
              SELECT pc_bal 
                FROM pettycash AS pc 
                WHERE pc.pc_date < since
                ORDER BY pc.pc_date DESC, pc.pc_id DESC LIMIT 1
            );
        IF ISNULL(sincebal) THEN
          SET sincebal=0.0;
        END IF;
        UPDATE pettycash AS pc
          SET pc_bal=(
            SELECT sincebal+SUM(net) 
              FROM (
                SELECT pc_id, pc_in - pc_out AS net, pc_date
                  FROM pettycash
                  WHERE since <= pc_date 
              ) AS older
              WHERE pc.pc_date > older.pc_date
                 OR (pc.pc_date = older.pc_date 
                     AND pc.pc_id >= older.pc_id)
          ) WHERE pc.pc_date >= since;
    END;;
    delimiter ;
    

    Off-topic

    A problem with the current schema is the use of Floats to store monetary values. Due to how floating point numbers are represented, numbers that are exact in base 10 (i.e. don’t have a repeating decimal representation) aren’t always exact as floats. For example, 0.01 (in base 10) will be closer to 0.009999999776482582… or 0.0100000000000000002081668… when stored. It’s rather like how 1/3 in base 3 is “0.1” but 0.333333…. in base 10. Instead of Float, you should use the Decimal type:

    ALTER TABLE pettycash MODIFY pc_in DECIMAL(10,2);
    ALTER TABLE pettycash MODIFY pc_out DECIMAL(10,2);
    

    If using a view, drop pettycash.pc_bal. If using a stored procedure to update pettycash.pc_bal, it too should be altered.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.