2016-06-07 57 views
3

我有運送燃料的表如下:如何按日期順序選擇總數達到任意數量的記錄?

Date  Time  Qty 
20160101 0800  4500 
20160203 0900  6000 
20160301 0810  3400 
20160328 1710  5300 
20160402 1201  6000 

我知道,在4月1日我在坦克有萬升所以現在我要選擇只是彌補了總的交付。這意味着我需要20160328,20160301和20160203的記錄。我正在使用Postgres,我想知道如何構建將完成此任務的選擇語句。 我明白如何使用where子句過濾日期少於4月1日的記錄,但我不知道如何指示Postgres以相反的日期順序選擇記錄,直到所選數量大於或等於10,000。

+0

這被稱爲RELA該部門https://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/ –

回答

0

您可以創建一個使用基於降序的日期和時間的順序,像這樣的窗口函數運行總計:

SELECT 
    Date, 
    Time, 
    Qty 
FROM 
(
SELECT 
    Date, 
    Time, 
    Qty, 
    SUM(Qty) OVER (ORDER BY Date DESC, Time DESC) AS Running_Total 
FROM 
    fuel_deliveries 
WHERE 
    Date < '20160402' 
) rt 
WHERE 
    Running_Total <= 10000; 

內/子查詢讓你運行總計,但之後要過濾在其上,該值爲小於或等於10000。

+0

這是一個開始,但不幸的是,這不會選擇第三個紀錄因爲運行總數超過10,000。一旦總數達到10,000或更多,我需要停下來。其次,當fuel_deliveries表保存多年的數據時,內部SQL將在現實生活中彙總數百萬條記錄。我希望能夠提高它的效率,因此只需要總計記錄直到總數超過10,000。 –

+0

也許我不明白,但除非恰好是這樣的總和,否則你不會讓它「完全停止」在10,000。它要麼會導致超過10000或更少 - 不可能完全是這樣。 – Nicarus

+0

是的,它不太可能會停在正好10,000的位置,所以我希望它在等於或超過10,000的第一個記錄上停下來,因此我知道所有可能的交付都構成了10,000。 –

1
with d as (
    select *, sum(qty) over (order by date desc, time desc) as total 
    from delivery 
    where date between '20160101' and '20160401' 
) 
select * 
from d 
where total < 10000 
union 
(
    select * 
    from d 
    where total >= 10000 
    order by date desc, time desc 
    limit 1 
) 
order by date desc, time desc 
; 
    date | time | qty | total 
------------+----------+------+------- 
2016-03-28 | 17:10:00 | 5300 | 5300 
2016-03-01 | 08:10:00 | 3400 | 8700 
2016-02-03 | 09:00:00 | 6000 | 14700 

數據:

create table delivery (date date, time time, qty int); 
insert into delivery (date, time, qty) values 
('20160101','0800',4500), 
('20160203','0900',6000), 
('20160301','0810',3400), 
('20160328','1710',5300), 
('20160402','1201',6000); 
+0

謝謝你,這工作正常。唯一的問題是決定如何使「與」更高效,因此我不累計多年的數據。 –

+0

@SimonWhite:只要將它限制在where子句中的合理時間範圍內。 –

+0

@SimonWhite:包含日期限制並修復了一個錯誤 –