2016-07-29 82 views
0

我有一個像這樣的表,我通過適度返工this數據+ SQL來顯示白天,但我想添加空天以及與在右手邊運行理貨。爆炸一個SQL表,並插入一行,每天不存在

╔════════════╦════════╦═════════╦════════╗ 
║ day  ║ num1 ║ num2 ║ tally ║ 
╠════════════╬════════╬═════════╬════════╣ 
║ 2016-06-10 ║ 9.99 ║   ║ 9.99 ║ 
║ 2016-06-12 ║ 136.00 ║ 9.99 ║ 145.99 ║ 
║ 2016-06-14 ║  ║ 145.99 ║ 145.99 ║ 
║ 2016-06-18 ║ 9.99 ║ 145.99 ║ 155.98 ║ 
║ 2016-06-19 ║ 210.00 ║ 145.99 ║ 365.98 ║ 
║ 2016-06-22 ║ 50.00 ║ 9.99 ║ 279.98 ║ 
║ 2016-06-28 ║ 69.99 ║ 59.99 ║ 349.97 ║ 
╚════════════╩════════╩═════════╩════════╝ 

我不知道如何讓這個錶轉換爲:

╔════════════╦════════╦═════════╦════════╗ 
║ day  ║ num1 ║ num2 ║ tally ║ 
╠════════════╬════════╬═════════╬════════╣ 
║ 2016-06-10 ║ 9.99 ║   ║ 9.99 ║ 
║ 2016-06-11 ║  ║   ║ 9.99 ║ <- new row with previous value 
║ 2016-06-12 ║ 136.00 ║ 9.99 ║ 145.99 ║ 
║ 2016-06-13 ║  ║   ║ 145.99 ║ <- new row with previous value 
║ 2016-06-14 ║  ║ 145.99 ║ 145.99 ║ 
║ 2016-06-15 ║  ║   ║ 145.99 ║ <- new row with previous value 
║ 2016-06-16 ║  ║   ║ 145.99 ║ <- new row with previous value 
║ 2016-06-17 ║  ║   ║ 145.99 ║ <- new row with previous value 
║ 2016-06-18 ║ 9.99 ║ 145.99 ║ 155.98 ║ 
║ 2016-06-19 ║ 210.00 ║ 145.99 ║ 365.98 ║ 
║ 2016-06-20 ║  ║   ║ 365.98 ║ <- new row with previous value 
║ 2016-06-21 ║  ║   ║ 365.98 ║ <- new row with previous value 
║ 2016-06-22 ║ 50.00 ║ 9.99 ║ 279.98 ║ 
║ 2016-06-23 ║  ║   ║ 279.98 ║ <- new row with previous value 
║ 2016-06-24 ║  ║   ║ 279.98 ║ <- new row with previous value 
║ 2016-06-25 ║  ║   ║ 279.98 ║ <- new row with previous value 
║ 2016-06-26 ║  ║   ║ 279.98 ║ <- new row with previous value 
║ 2016-06-27 ║  ║   ║ 279.98 ║ <- new row with previous value 
║ 2016-06-28 ║ 69.99 ║ 59.99 ║ 349.97 ║ 
╚════════════╩════════╩═════════╩════════╝ 
+0

數據庫是否有這對於每一日的記錄日曆類型的表? –

+0

@DanBracuk是的,這是第一個表,但它只創建一個記錄存在時的行。我需要一堆空白的日期行,即使所有其他值對於該行都是空白的,也會帶來理貨值。 – eveo

回答

1

試試這個(我假設你的表稱爲tbl)。我使用generate_series來生成缺失的行,並使用幾個窗口函數在新行中插入適當的tally值。

with all_dates as (
    SELECT day 
    FROM generate_series 
     ('2016-06-10'::date, 
     '2016-06-28'::date, 
     '1 day'::interval) day 
), partitioned_data as (
    select d.day, t.num1, t.num2, t.tally, 
     sum(case when t.tally is not null then 1 else 0 end) over (order by d.day) as partition_id 
    from all_dates d 
    left join tbl t 
     on t.day = d.day 
) 
select t.day, t.num1, t.num2, 
     first_value(t.tally) over (partition by t.partition_id) as tally 
    from partitioned_data t 
order by t.day 
+0

這很好用,謝謝。剩下的問題是獲取範圍的開始日期和結束日期,我想從「invoices」表中獲取該範圍的起始日期和結束日期,列「start」具有開始日期,列「end」具有結束日期。我想找到'start'列的最小值和'end'列的最大值,並將這些列用於範圍。 – eveo

+0

編輯,nvm我明白了!儘管我認爲這有點複雜 – eveo

1

數據:

create table the_data(day date, num1 numeric, num2 numeric, tally numeric); 
insert into the_data values 
('2016-06-10', 9.99, null, 9.99), 
('2016-06-12', 136.00, 9.99, 145.99), 
('2016-06-14', null, 145.99, 145.99), 
('2016-06-18', 9.99, 145.99, 155.98), 
('2016-06-19', 210.00, 145.99, 365.98), 
('2016-06-22', 50.00, 9.99, 279.98), 
('2016-06-28', 69.99, 59.99, 349.97); 

查詢:

with the_data as ( 
    select d::date as day, num1, num2, tally 
    from generate_series('2016-06-10'::date, '2016-06-28', '1d') d 
    left join the_data on d = day 
    ) 
select distinct on (a.day) a.day, a.num1, a.num2, b.tally 
from the_data a 
join the_data b 
on a.day >= b.day and b.tally is not null 
order by a.day, b.day desc; 

    day  | num1 | num2 | tally 
------------+--------+--------+-------- 
2016-06-10 | 9.99 |  | 9.99 
2016-06-11 |  |  | 9.99 
2016-06-12 | 136.00 | 9.99 | 145.99 
2016-06-13 |  |  | 145.99 
2016-06-14 |  | 145.99 | 145.99 
2016-06-15 |  |  | 145.99 
2016-06-16 |  |  | 145.99 
2016-06-17 |  |  | 145.99 
2016-06-18 | 9.99 | 145.99 | 155.98 
2016-06-19 | 210.00 | 145.99 | 365.98 
2016-06-20 |  |  | 365.98 
2016-06-21 |  |  | 365.98 
2016-06-22 | 50.00 | 9.99 | 279.98 
2016-06-23 |  |  | 279.98 
2016-06-24 |  |  | 279.98 
2016-06-25 |  |  | 279.98 
2016-06-26 |  |  | 279.98 
2016-06-27 |  |  | 279.98 
2016-06-28 | 69.99 | 59.99 | 349.97 
(19 rows) 
+0

感謝您爲我的示例創建表查詢。 – eveo

+0

OP與回答者之間溝通的最佳方式是以文本格式提供數據結構和樣本數據,以便重現結果和可能的錯誤。不幸的是,大多數OP沒有意識到這一點。 – klin

+0

是的,我試圖搞砸SQLFiddle,結果弄了半個小時就搞不定它了。 – eveo