简体   繁体   中英

How to achieve this complex sum of 2 rows from a MYSQL result set?

Let's say I have a table like this (dollar sign here just to prettify...):

DATE        | CREDIT    | DEBIT
2013-11-28  | $ 100     | $ 0
2013-11-29  | $ 20      | $ -10
2013-12-01  | $ 150     | $ 0
2013-12-02  | $ 100     | $ -10

After some research, what I achieved so far (part of what I needed), making use of MYSQL user variables is this:

DATE        | CREDIT    | DEBIT    | MONTH SUM   | TOTAL SUM   | MONTH
2013-11-28  | $ 100     | $ 0      | $ 100       | $ 100       | 11
2013-11-29  | $ 20      | $ -10    | $ 110       | $ 110       | 11
2013-12-01  | $ 150     | $ 0      | $ 150       | $ 260       | 12
2013-12-02  | $ 100     | $ -10    | $ 240       | $ 350       | 12


This is the MYSQL query I used in order to get these results:

SELECT V.*,
IF(DATE_FORMAT(date, '%m') != @month,
@month_sum := credit + debit,
@month_sum := @month_sum + (credit + debit)) as month_sum,
@total_sum := @total_sum + (credit + debit) as total_sum,
@month := DATE_FORMAT(date,'%m') as month
FROM tbl_values V
JOIN (SELECT @month := 0, @month_sum := 0, @total_sum := 0) D
ORDER BY date ASC


Now, here's where the tricky part comes in: Let's say I want to paginate these results on the PHP page where i'm using these results for each 2 rows (for simplicity's sake).
If I try to do it using the LIMIT clause, I'll lose the MYSQL user variable value from the last page (cause i'm setting them to 0 on the JOIN clause, but if I don't do it, things won't go well, believe me).

Is there a way to do this only in MYSQL using a single query ? If not, it's okay using 2 or more queries, but I should be able to paginate through the results keeping the values from the previous "month_sum" and "total_sum" rows.
Maybe I should leave MYSQL alone and try and achieve this only through PHP ?
Keep in mind that performance is an issue here as well, as I can't tell for sure how many records I'll be dealing with, probably more than thousands soon enough.

Here's the table structure and data, in case you guys wanna test it out. Any direction is appreciated, thank you !

-- STRUCTURE:    
CREATE TABLE IF NOT EXISTS `tbl_values` (
`date` date NOT NULL,
`credit` float NOT NULL,
`debit` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- DATA
INSERT INTO `tbl_values` (`date`, `credit`, `debit`) VALUES
('2013-11-28', 100, 0),
('2013-11-29', 20, -10),
('2013-12-01', 150, 0),
('2013-12-02', 100, -10);

Something like this?

SELECT * FROM(SELECT V.*,
IF(DATE_FORMAT(date, '%m') != @month,
@month_sum := credit + debit,
@month_sum := @month_sum + (credit + debit)) as month_sum,
@total_sum := @total_sum + (credit + debit) as total_sum,
@month := DATE_FORMAT(date,'%m') as month
FROM tbl_values V
JOIN (SELECT @month := 0, @month_sum := 0, @total_sum := 0) D
ORDER BY date ASC)z LIMIT 2

SQL Fiddle

It is probably better to do this in PHP when displaying the data. Once you have created the query, you can use the data_seek method to move to the first row you wish to display.

So, if you are on page one, you start at row 1 and display say 15 rows. On page x you seek the appropriate row and then loop from there onwards.

See: http://www.php.net/manual/en/mysqli-result.data-seek.php

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM