首先,你的设计有缺陷。time
不利于这个目的。过了午夜,它就中断了。使用timestamp
或timestamptz
代替。
接下来,由于在 PostgreSQL 中不带引号的标识符会自动转换为小写,因此您的命名约定也不好。我把它改编成更有用的东西。
CREATE TABLE boxes (box_id int PRIMARY KEY, box_name text, box_cost numeric);
INSERT INTO boxes VALUES
(1, 'Bob''s Box', 20)
,(2, 'Matt''s Box', 21)
,(3, 'Jacob''s Box', 22)
,(4, 'Beth''s Box', 23)
,(5, 'Rachel''s Box', 24);
CREATE TABLE box_processids (
box_id int
,parentprocess_id int
,PRIMARY KEY(box_id, parentprocess_id)
);
INSERT INTO box_processids VALUES
(1, 123)
,(2, 456)
,(3, 789)
,(4, 012)
,(5, 234);
CREATE TABLE box_processes (
parentprocess_id int
,childprocess_id char(3)
,start_time timestamp
,end_time timestamp
,processname text
,PRIMARY KEY(parentprocess_id, childprocess_id)
);
INSERT INTO box_processes VALUES
(123, 'AAA', '2013-2-10 1:00', '2013-2-10 1:05', 'Invoiced')
,(123, 'AAB', '2013-2-10 1:30', '2013-2-10 1:35', 'Packed')
,(123, 'BBB', '2013-2-10 2:00', '2013-2-10 2:05', 'Shipped')
,(456, 'CDD', '2013-2-10 3:15', '2013-2-10 3:20', 'Invoiced')
,(456, 'DDD', '2013-2-10 3:25', '2013-2-10 3:30', 'Packaging_Complete')
,(456, 'CCD', '2013-2-10 3:35', '2013-2-10 3:40', 'Shipped')
,(789, 'EEE', '2013-2-10 4:15', '2013-2-10 4:20', 'Invoiced')
,(789, 'EEF', '2013-2-10 4:25', '2013-2-10 4:30', 'Done_Packing')
,(789, 'EFF', '2013-2-10 4:35', '2013-2-10 4:40', 'Shipped');
您的查询可能如下所示:
SELECT b.box_name
,b.box_cost
,(i.end_time - i.start_time) AS box_invoice_duration
,(p.end_time - p.start_time) AS box_packing_duration
,(s.end_time - s.start_time) AS box_shipping_duration
FROM boxes b
LEFT JOIN box_processids bp USING (box_id)
LEFT JOIN box_processes i ON i.parentprocess_id = bp.parentprocess_id
AND i.processname = 'Invoiced'
LEFT JOIN box_processes p ON i.parentprocess_id = bp.parentprocess_id
AND p.processname = 'Packed'
LEFT JOIN box_processes s ON i.parentprocess_id = bp.parentprocess_id
AND s.processname = 'Shipped'
->sqlfiddle
用于to_char()
格式化您interval
想要的任何方式。