怎么用语句查询得出这样一个表?万分感谢!
不知道需要把行变成列,而且每列对应的结果要减去前面累积的和。请看下图。每个PO对应的型号有表,每个型号对应的工艺流程有表,PO对应的交期也是已知数。怎么统计成生产计划?
如果是oracle数据库,可以用pivot;
如果是其他的数据库,通用写法就是case when,而且你这固定列了用case when也没毛病。
另外,如果要写得不套那么多层的话,需要数据库支持开窗函数或者递归,比如sqlserver2017、mysql8、oracle等数据库。
当然,既然前面这个流程表有固定的值,那么不介意再添加一列,第5行等于10、第4行等于18、第3行等于23,以此类推,这样可以让sql得到简化
先来个oracle的
create table step_test (id number,name varchar2(1),hour number);
insert into step_test (ID, NAME, HOUR)
values (1, 'A', 8);
insert into step_test (ID, NAME, HOUR)
values (2, 'B', 16);
insert into step_test (ID, NAME, HOUR)
values (3, 'C', 5);
insert into step_test (ID, NAME, HOUR)
values (4, 'D', 8);
insert into step_test (ID, NAME, HOUR)
values (5, 'E', 10);
commit;
select *
from (select NAME,
date '2021-01-05' -
(sum(hour) over(order by id desc rows
between UNBOUNDED PRECEDING and current row)) / 24 hh
from step_test x)
pivot(max(hh)
for name in('A' A, 'B' B, 'C' C, 'D' D, 'E' E))
-- 工艺流程
CREATE TABLE `step` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(1) NOT NULL,
`hour` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `step` VALUES ('1', 'A', '8');
INSERT INTO `step` VALUES ('2', 'B', '16');
INSERT INTO `step` VALUES ('3', 'C', '5');
INSERT INTO `step` VALUES ('4', 'D', '8');
INSERT INTO `step` VALUES ('5', 'E', '10');
-- PO流程
CREATE TABLE `po_step` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`po_id` int(11) NOT NULL,
`step_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `po_step` VALUES ('1', '1', '1');
INSERT INTO `po_step` VALUES ('2', '1', '2');
INSERT INTO `po_step` VALUES ('3', '1', '3');
INSERT INTO `po_step` VALUES ('4', '1', '4');
INSERT INTO `po_step` VALUES ('5', '1', '5');
-- 最终的sql
select po_id,
max(case when name = 'A' then DATE_SUB('2022-01-05 00:00:00',INTERVAL totol_time HOUR)else '0000-00-00 00:00:00' end) as 'A',
max(case when name = 'B' then DATE_SUB('2022-01-05 00:00:00',INTERVAL totol_time HOUR)else '0000-00-00 00:00:00' end) as 'B',
max(case when name = 'C' then DATE_SUB('2022-01-05 00:00:00',INTERVAL totol_time HOUR)else '0000-00-00 00:00:00' end) as 'C',
max(case when name = 'D' then DATE_SUB('2022-01-05 00:00:00',INTERVAL totol_time HOUR)else '0000-00-00 00:00:00' end) as 'D',
max(case when name = 'E' then DATE_SUB('2022-01-05 00:00:00',INTERVAL totol_time HOUR)else '0000-00-00 00:00:00' end) as 'E'
from (
select t.*,
if(@curPid=t.po_id,@total:=@total+hour, @total:=t.hour) as totol_time,@curPid:=po_id
from
(
select p.*,s.name,s.hour,(select @total:=0),(select @curPid:=null)
from po_step p
join step s on p.step_id = s.id
-- where 条件
ORDER BY po_id,step_id desc
)t
)t2
GROUP BY po_id
效果
ps:mysql 没有现成函数进行行转列,用case when 可以实现,但有局限,不能动态,都是写死的列。