簡體   English   中英

Postgres有條件選擇嗎?

[英]Postgres Conditional Select?

我不太確定如何在沒有示例的情況下描述此問題,所以這里有一個示例:

我有三個表:

表1:盒子

BoxID | Box Name | Box Cost
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

表2:Box_ProcessID

BoxID | ParentProcessID
1 | 123
2 | 456
3 | 789
4 | 012
5 | 234

表3:Box_Processes

ParentProcess | ChildProcess | Start Time | End Time | ProcessName 
123 | AAA | 1:00 | 1:05 | Invoiced
123 | AAB | 1:30 | 1:35 | Packed
123 | BBB | 2:00 | 2:05 | Shipped

456 | CDD | 3:15 | 3:20 | Invoiced
456 | DDD | 3:25 | 3:30 | Packaging_Complete
456 | CCD | 3:35 | 3:40 | Shipped

789 | EEE | 4:15 | 4:20 | Invoiced
789 | EEF | 4:25 | 4:30 | Done_Packing
789 | EFF | 4:35 | 4:40 | Shipped

我希望輸出列為:框名稱,框成本,框運輸持續時間,框包裝持續時間,框發票持續時間

我知道我可以像%pack%一樣選擇包裝字段,並且可以弄清楚如何使用Date_Part或類似的方法來獲取工期,但是我對如何獲取shipping durationpacking duration ,和invoice duration到單獨的字段中。

因此,您想執行類似此偽sql的操作嗎?

select b.box_name, b.box_cost,
bp2.end_time - bp2.start_time as box_shipping_duration,
bp3.end_time - bp3.start_time as box_packing_duration,
bp1.end_time - bp1.start_time as box_invoice_duration
from boxes b

join box_processids bpid on b.boxid = bpid.boxid

left outer join box_processes bp1 on bpid.parentprocessid = bp1.parentprocess
and processname = 'Invoiced'

left outer join box_processes bp2 on bpid.parentprocessid = bp2.parentprocess
and processname = 'Shipped'

left outer join box_processes bp3 on bpid.parentprocessid = bp3.parentprocess
and processname = 'Packed'

(將需要空檢查,正確的日期時間處理,更好的名稱等)

首先,您的設計存在缺陷。 time對於這個目的沒有好處。 越過午夜,它就會中斷。 請改用timestamptimestamptz

接下來,由於在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格式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM