Какой самый эффективный способ подсчета промежуточного итога / баланса при использовании нумерации страниц (PHP, MySQL)

У меня есть таблица MySQL, в которой хранятся записи о пробегах, зарегистрированные сотрудниками. У меня есть страница PHP, которая выводит записи о пробеге для каждого сотрудника в таблице (от самого нового до самого старого) вместе с текущим балансом. Это все отлично работает.

Показатели пробега растут быстрее, чем ожидалось, и теперь стало очевидно, что нумерация страниц необходима. Я запрограммировал нумерацию страниц, и это прекрасно работает. Проблема, с которой я столкнулся, состоит в том, что нумерация страниц «нарушила» текущий баланс таким образом, что он игнорирует любые значения за пределами записей, которые я выбрал. Например, представьте, что ваш банковский счет только что предоставил баланс за июль месяц без учета того, что было на вашем счете в июне.

Буду очень признателен за предложения о том, как решить эту проблему в теории (мне не нужен построчный код), так как Google не выдает большой помощи.

РЕДАКТИРОВАТЬ 1

Database and data

-- phpMyAdmin SQL Dump
-- version 4.0.10.14
-- http://www.phpmyadmin.net
--
-- Host: localhost:3306
-- Generation Time: Jul 21, 2016 at 07:11 PM
-- Server version: 5.1.73-cll
-- PHP Version: 5.4.31

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

--
-- Database: `propsyst_main`
--

-- --------------------------------------------------------

--
-- Table structure for table `employee_mileage`
--

CREATE TABLE IF NOT EXISTS `employee_mileage` (
`employee_mileage_id` int(11) NOT NULL AUTO_INCREMENT,
`employee_mileage_employee_id` int(11) DEFAULT NULL,
`employee_mileage_vehicle_id` smallint(6) DEFAULT NULL,
`employee_mileage_start_postcode` varchar(8) COLLATE utf8_bin DEFAULT NULL,
`employee_mileage_end_postcode` varchar(8) COLLATE utf8_bin DEFAULT NULL,
`employee_mileage_mileage` decimal(6,2) DEFAULT NULL,
PRIMARY KEY (`employee_mileage_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=8 ;

--
-- Dumping data for table `employee_mileage`
--

INSERT INTO `employee_mileage` (`employee_mileage_id`, `employee_mileage_employee_id`, `employee_mileage_vehicle_id`, `employee_mileage_start_postcode`, `employee_mileage_end_postcode`, `employee_mileage_mileage`) VALUES
(1, 1, 2, 'L17 0BZ', 'L36 9TJ', '1.00'),
(2, 1, 2, 'L17 0BZ', 'L36 9TJ', '2.00'),
(3, 1, 2, 'L17 0BZ', 'L36 9TJ', '3.00'),
(4, 1, 2, 'L17 0BZ', 'L36 9TJ', '4.00'),
(5, 1, 2, 'L17 0BZ', 'L36 9TJ', '5.00'),
(6, 1, 2, 'L17 0BZ', 'L36 9TJ', '6.00'),
(7, 1, 2, 'L17 0BZ', 'L36 9TJ', '7.00');

РЕДАКТИРОВАТЬ 2

Попытка запроса, которая не работает;

$statement = "SELECT *
from (
SELECT     em.*, e.*,
@balance := @balance + em.employee_mileage_mileage as balance
FROM       employee_mileage em
CROSS JOIN (select   @balance := 0) init
INNER JOIN employee e
on em.employee_mileage_employee_id = e.employee_id
where      em.employee_mileage_employee_id = " . $employee_id . "order by   em.employee_mileage_id
) as base
ORDER BY   em.employee_mileage_id DESC";

$employee_mileage_query = mysqli_query($con,"{$statement} LIMIT {$startpoint} , {$per_page}") or die(mysql_error());

РЕДАКТИРОВАТЬ 3

База данных;

-- phpMyAdmin SQL Dump
-- version 4.0.10.14
-- http://www.phpmyadmin.net
--
-- Host: localhost:3306
-- Generation Time: Jul 25, 2016 at 10:22 PM
-- Server version: 5.1.73-cll
-- PHP Version: 5.4.31

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

--
-- Database: `propsyst_main`
--

-- --------------------------------------------------------

--
-- Table structure for table `employee_mileage`
--

CREATE TABLE IF NOT EXISTS `employee_mileage` (
`employee_mileage_id` int(11) NOT NULL AUTO_INCREMENT,
`employee_mileage_employee_id` int(11) DEFAULT NULL,
`employee_mileage_vehicle_id` smallint(6) DEFAULT NULL,
`employee_mileage_journey_date` date DEFAULT NULL,
`employee_mileage_start_postcode` varchar(8) COLLATE utf8_bin DEFAULT NULL,
`employee_mileage_end_postcode` varchar(8) COLLATE utf8_bin DEFAULT NULL,
`employee_mileage_mileage` decimal(6,2) DEFAULT NULL,
`employee_mileage_date_created` datetime DEFAULT NULL,
`employee_mileage_created_by` int(11) DEFAULT NULL,
PRIMARY KEY (`employee_mileage_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=7 ;

--
-- Dumping data for table `employee_mileage`
--

INSERT INTO `employee_mileage` (`employee_mileage_id`, `employee_mileage_employee_id`, `employee_mileage_vehicle_id`, `employee_mileage_journey_date`, `employee_mileage_start_postcode`, `employee_mileage_end_postcode`, `employee_mileage_mileage`, `employee_mileage_date_created`, `employee_mileage_created_by`) VALUES
(1, 32, 1, '2016-07-15', 'L17 0BZ', 'L6 5BJ', '4.19', '2016-07-25 10:15:01', 32),
(2, 32, 1, '2016-07-15', 'L6 5BJ', 'L17 0BZ', '4.19', '2016-07-25 10:15:01', 32),
(5, 32, 1, '2016-07-23', 'L17 0BZ', 'L17 1AE', '1.55', '2016-07-25 12:14:15', 32),
(3, 32, 1, '2016-07-21', 'L17 0BZ', 'L19 0PD', '2.03', '2016-07-25 12:09:24', 32),
(4, 32, 1, '2016-07-21', 'L19 0PD', 'L17 0BZ', '2.03', '2016-07-25 12:09:24', 32),
(6, 32, 1, '2016-07-23', 'L17 1AE', 'L17 0BZ', '1.55', '2016-07-25 12:14:15', 32);

Запрос;

$statement = "SELECT *
from (
SELECT     em.*, e.*, v.*,
@balance := @balance + em.employee_mileage_mileage as balance
FROM       employee_mileage em
CROSS JOIN (select @balance := 0) init
INNER JOIN employee e
on em.employee_mileage_employee_id = e.employee_id
INNER JOIN vehicle v
on em.employee_mileage_vehicle_id = v.vehicle_id
WHERE      em.employee_mileage_employee_id = " . $employee_id . "ORDER BY   em.employee_mileage_id
) as base
ORDER BY base.employee_mileage_id DESC";

$employee_mileage_query = mysqli_query($con,"{$statement} LIMIT {$startpoint} , {$per_page}") or die(mysql_error());

Выход;

введите описание изображения здесь

1

Решение

Я бы посоветовал рассчитать текущий баланс в вашем SQL-запросе.

Вот пример того, как может выглядеть этот оператор SQL:

SELECT *
from (
SELECT     *,
@balance := @balance + em.employee_mileage_mileage as balance
FROM       (select     em.*, e.*, v.*
from       employee_mileage em
INNER JOIN employee e
on em.employee_mileage_employee_id = e.employee_id
INNER JOIN vehicle v
on em.employee_mileage_vehicle_id = v.vehicle_id
WHERE      em.employee_mileage_employee_id = ?
ORDER BY   em.employee_mileage_id ASC
) em
CROSS JOIN (select @balance := 0) init
) as base
ORDER BY base.employee_mileage_id DESC
LIMIT   ?, 2

Параметры в приведенном выше утверждении (отмечены ?) должен быть связан с:

  • employee_id Вы хотите показать данные для
  • начальная строка текущей страницы (начиная с нуля)

Внутренний запрос проходит через все строки для этого конкретного сотрудника и добавляет текущий баланс к каждой записи. Затем внешний запрос меняет порядок сортировки и применяет к нему ограничение для целей подкачки.

Это решение не требует каких-либо вычислений в PHP; текущий баланс легко доступен в наборе результатов запроса и корректен на каждой странице.

Вот маленький SQL скрипка демонстрация его для получения второй страницы, по 2 строки на страницу, из общего набора из 6 строк, включая правильный баланс.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]