我坚持按照id / rev对这个表中的项目求和。
我需要从内容字段中减去值来计算总和。交货是加号,退货是减去 记录有一个时间戳,我需要在最后一次复位之前得到表中不同id的s。例如,ID1在2018-01-12 14:10有一个LAST重置,我只需要在此日期之后的3个SYSx总和。是否可以在一个查询中获得9个总和?
我需要以下结果:
ID1 SYS1 +/-x items (delivered items - returned items until the most reset for this ID)
ID1 SYS2 +/-x items
ID1 SYS3 +/-x items
ID2 SYS1 +/-x items
ID2 SYS2 +/-x items
ID2 SYS3 +/-x items
ID3 SYS1 +/-x items
ID3 SYS2 +/-x items
ID3 SYS3 +/-x items
CREATE TABLE docs (
tDate DATETIME NULL,
id varchar(200) NOT NULL,
rev varchar(200)NOT NULL,
content varchar(200) NOT NULL
);
INSERT INTO docs (tDate, id, rev, content) VALUES
('2018-01-13 12:10','ID1', 'SYS1', 'returned 3 items'),
('2018-01-13 12:05','ID1', 'SYS2', 'delivered items: 4'),
('2018-01-13 12:00','ID2', 'SYS3', 'returned 2 items'),
('2018-01-12 14:10','ID1', 'RESET', ''),
('2018-01-12 12:50','ID2', 'SYS1', 'delivered items: 1'),
('2018-01-12 12:40','ID3', 'SYS2', 'returned 1 item'),
('2018-01-12 12:30','ID3', 'SYS3', 'delivered items: 1'),
('2018-01-12 12:20','ID2', 'SYS1', 'delivered items: 1'),
('2018-01-11 12:00','ID3', 'SYS2', 'returned 1 item'),
('2018-01-11 12:00','ID1', 'SYS2', 'delivered items: 1'),
('2018-01-11 12:00','ID3', 'SYS3', 'returned 3 items'),
('2018-01-10 12:10','ID1', 'RESET', ''),
('2018-01-10 12:00','ID2', 'SYS3', 'delivered items: 1'),
('2018-01-10 12:00','ID3', 'SYS1', 'delivered items: 1'),
('2018-01-09 13:20','ID2', 'SYS2', 'delivered items: 3'),
('2018-01-08 14:00','ID3', 'SYS1', 'delivered items: 1'),
('2018-01-07 14:10','ID3', 'RESET', ''),
('2018-01-07 12:00','ID1', 'SYS2', 'returned 2 items'),
('2018-01-06 13:00','ID1', 'SYS1', 'delivered items: 1'),
('2018-01-05 14:00','ID2', 'SYS2', 'delivered items: 3'),
('2018-01-05 13:00','ID2', 'SYS3', 'delivered items: 2'),
('2018-01-05 12:00','ID3', 'SYS2', 'returned 1 item'),
('2018-01-04 17:00','ID3', 'SYS1', 'delivered items: 2'),
('2018-01-03 17:10','ID2', 'RESET', ''),
('2018-01-02 18:00','ID2', 'SYS3', 'delivered items: 2'),
('2018-01-01 19:00','ID3', 'SYS2', 'returned 1 item');
答案 0 :(得分:0)
Solution has two part:
**first 1 is a function:**
DELIMITER $$
CREATE FUNCTION `ExtractNumber`(in_string VARCHAR(50))
RETURNS INT
NO SQL
BEGIN
DECLARE ctrNumber VARCHAR(50);
DECLARE finNumber VARCHAR(50) DEFAULT '';
DECLARE sChar VARCHAR(1);
DECLARE inti INTEGER DEFAULT 1;
IF LENGTH(in_string) > 0 THEN
WHILE(inti <= LENGTH(in_string)) DO
SET sChar = SUBSTRING(in_string, inti, 1);
SET ctrNumber = FIND_IN_SET(sChar, '0,1,2,3,4,5,6,7,8,9');
IF ctrNumber > 0 THEN
SET finNumber = CONCAT(finNumber, sChar);
END IF;
SET inti = inti + 1;
END WHILE;
RETURN CAST(finNumber AS UNSIGNED);
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;
**second one is output SQL:**
SELECT s.*, SUM(
IF(tDate<=max_tDate AND (content LIKE '%delivered%'),qty,
IF(tDate<=max_tDate AND (content LIKE '%returned%'),-qty,0)) ) summ FROM
(
SELECT docs.*, ExtractNumber(content) qty, mx.max_tDate FROM docs
LEFT OUTER JOIN (SELECT id, MAX(tDate) max_tDate FROM docs WHERE rev='RESET' GROUP BY id) mx ON(docs.id=mx.id)
ORDER BY docs.tDate
) s
GROUP BY s.id