Ежедневный инвентарь из журнала купленных / проданных транзакций - PullRequest
0 голосов
/ 19 февраля 2020

Следующие запросы SQL описывают две таблицы и их содержимое, небольшую и упрощенную часть большой системы инвентаризации.

Первый - журнал транзакций, в котором перечисляются купленные и проданные количества различных предметов.

CREATE TABLE `Inventar_actions` (
  `PartID` char(8) NOT NULL,
  `DateSeq` smallint(4) unsigned NOT NULL,
  `ActionType` enum('Bought','Sold') NOT NULL,
  `Units` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`PartID`,`DateSeq`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `test`.`Inventar_actions` (`PartID`, `DateSeq`, `ActionType`, `Units`) VALUES 
('0001', '1020', 'Bought', '100'),('0001', '1025', 'Sold', '20'),('0001', '1028', 'Sold', '30'),
('0001', '1031', 'Bought', '100'),('0001', '1035', 'Sold', '50');

Вторая таблица - это календарь, в котором перечислены рабочие дни и их порядковые номера из произвольной эпохи:

CREATE TABLE `BusinessDates` (
  `DateSeq` int(10) unsigned NOT NULL,
  `BusinessDate` date NOT NULL,
  PRIMARY KEY (`DateSeq`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `test`.`BusinessDates` (`DateSeq`, `BusinessDate`) VALUES 
('1015', '2020-02-03'),('1016', '2020-02-04'),('1017', '2020-02-05'),('1018', '2020-02-06'),('1019', '2020-02-07'),
('1020', '2020-02-10'),('1021', '2020-02-11'),('1022', '2020-02-12'),('1023', '2020-02-13'),('1024', '2020-02-14'),
('1025', '2020-02-17'),('1026', '2020-02-18'),('1027', '2020-02-19'),('1028', '2020-02-20'),('1029', '2020-02-21'),
('1030', '2020-02-24'),('1031', '2020-02-25'),('1032', '2020-02-26'),('1033', '2020-02-27'),('1034', '2020-02-28'),
('1035', '2020-03-02'),('1036', '2020-03-03'),('1037', '2020-03-04'),('1038', '2020-03-05'),('1039', '2020-03-06')
;

Мне нужен ежедневный инвентарь, который выглядит примерно так:

| 1020 | 2020-02-10 | 100 | Bought | 100 |
| 1021 | 2020-02-11 |     |        | 100 |
| 1022 | 2020-02-12 |     |        | 100 |
| 1023 | 2020-02-13 |     |        | 100 |
| 1024 | 2020-02-14 |     |        | 100 |
| 1025 | 2020-02-17 |  20 | Sold   |  80 |
| 1026 | 2020-02-18 |     |        |  80 |
| 1027 | 2020-02-19 |     |        |  80 |
| 1028 | 2020-02-20 |  30 | Sold   |  50 |
| 1029 | 2020-02-21 |     |        |  50 |
| 1030 | 2020-02-24 |     |        |  50 |
| 1031 | 2020-02-25 | 100 | Bought | 150 |
| 1032 | 2020-02-26 |     |        | 150 |
| 1033 | 2020-02-27 |     |        | 150 |
| 1034 | 2020-02-28 |     |        | 150 |
| 1035 | 2020-03-02 |  50 | Sold   | 100 |
| 1036 | 2020-03-03 |     |        | 100 |
| 1037 | 2020-03-04 |     |        | 100 |
| 1038 | 2020-03-05 |     |        | 100 |
| 1039 | 2020-03-06 |     |        | 100 |

То есть для каждой рабочей даты, каково сальдо каждого PartID, с учетом купленных и проданных деталей.

Я использовал следующий запрос, чтобы выстроить даты, последовательность дат и транзакции:

SELECT d.DateSeq, d.BusinessDate, a.`Units`, a.`ActionType` 
FROM `BusinessDates` AS d LEFT JOIN 
(SELECT DateSeq, ActionType, Units FROM `Inventar_actions` WHERE PartID = '0001') AS a USING (DateSeq)
WHERE d.DateSeq BETWEEN 1020 AND 1039
ORDER BY d.DateSeq;

Это приводит к первым четырем столбцам желаемого вывода.

К сожалению, я не смог найти запрос, который также будет производить последний столбец, баланс запасов деталей .

Обратите внимание, что существует много PartID и тысячи рабочих дней.

Пожалуйста, помогите ...

1 Ответ

1 голос
/ 19 февраля 2020

Работает с mysql 5.x и 8.0

CREATE TABLE `Inventar_actions` (
  `PartID` char(8) NOT NULL,
  `DateSeq` smallint(4) unsigned NOT NULL,
  `ActionType` enum('Bought','Sold') NOT NULL,
  `Units` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`PartID`,`DateSeq`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Inventar_actions` (`PartID`, `DateSeq`, `ActionType`, `Units`) VALUES 
('0001', '1020', 'Bought', '100'),('0001', '1025', 'Sold', '20'),('0001', '1028', 'Sold', '30'),
('0001', '1031', 'Bought', '100'),('0001', '1035', 'Sold', '50');
✓

✓
CREATE TABLE `BusinessDates` (
  `DateSeq` int(10) unsigned NOT NULL,
  `BusinessDate` date NOT NULL,
  PRIMARY KEY (`DateSeq`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `BusinessDates` (`DateSeq`, `BusinessDate`) VALUES 
('1015', '2020-02-03'),('1016', '2020-02-04'),('1017', '2020-02-05'),('1018', '2020-02-06'),('1019', '2020-02-07'),
('1020', '2020-02-10'),('1021', '2020-02-11'),('1022', '2020-02-12'),('1023', '2020-02-13'),('1024', '2020-02-14'),
('1025', '2020-02-17'),('1026', '2020-02-18'),('1027', '2020-02-19'),('1028', '2020-02-20'),('1029', '2020-02-21'),
('1030', '2020-02-24'),('1031', '2020-02-25'),('1032', '2020-02-26'),('1033', '2020-02-27'),('1034', '2020-02-28'),
('1035', '2020-03-02'),('1036', '2020-03-03'),('1037', '2020-03-04'),('1038', '2020-03-05'),('1039', '2020-03-06')
;
✓

✓
SELECT 
   d.DateSeq
   , d.BusinessDate
   , a.`Units`
   , a.`ActionType`
      , 
   CASE 
     WHEN a.`ActionType` = 'Bought' THEN @inventory := @inventory + a.`Units`
   WHEN a.`ActionType` = 'Sold' THEN @inventory := @inventory - a.`Units`
   ELSE
    @inventory := @inventory
   END inventory
FROM (SELECT * FROM `BusinessDates` ORDER BY  BusinessDate ASC) AS d LEFT JOIN 
(SELECT DateSeq, ActionType, Units FROM `Inventar_actions` WHERE PartID = '0001') AS a USING (DateSeq)
,(SELECT @inventory := 0) b
WHERE d.DateSeq BETWEEN 1020 AND 1039
ORDER BY d.DateSeq;
DateSeq | BusinessDate | Units | ActionType | inventory
------: | :----------- | ----: | :--------- | :--------
   1020 | 2020-02-10   |   100 | Bought     | 100      
   1021 | 2020-02-11   |  <em>null</em> | <em>null</em>       | 100      
   1022 | 2020-02-12   |  <em>null</em> | <em>null</em>       | 100      
   1023 | 2020-02-13   |  <em>null</em> | <em>null</em>       | 100      
   1024 | 2020-02-14   |  <em>null</em> | <em>null</em>       | 100      
   1025 | 2020-02-17   |    20 | Sold       | 80       
   1026 | 2020-02-18   |  <em>null</em> | <em>null</em>       | 80       
   1027 | 2020-02-19   |  <em>null</em> | <em>null</em>       | 80       
   1028 | 2020-02-20   |    30 | Sold       | 50       
   1029 | 2020-02-21   |  <em>null</em> | <em>null</em>       | 50       
   1030 | 2020-02-24   |  <em>null</em> | <em>null</em>       | 50       
   1031 | 2020-02-25   |   100 | Bought     | 150      
   1032 | 2020-02-26   |  <em>null</em> | <em>null</em>       | 150      
   1033 | 2020-02-27   |  <em>null</em> | <em>null</em>       | 150      
   1034 | 2020-02-28   |  <em>null</em> | <em>null</em>       | 150      
   1035 | 2020-03-02   |    50 | Sold       | 100      
   1036 | 2020-03-03   |  <em>null</em> | <em>null</em>       | 100      
   1037 | 2020-03-04   |  <em>null</em> | <em>null</em>       | 100      
   1038 | 2020-03-05   |  <em>null</em> | <em>null</em>       | 100      
   1039 | 2020-03-06   |  <em>null</em> | <em>null</em>       | 100      

дБ <> скрипка здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...