分解sql表并在不存在sql表的情况下每天插入一行
我有一个这样的表,它是通过稍微修改data+SQL生成的,以按天显示,但我想在右边添加空天数和运行计数分解sql表并在不存在sql表的情况下每天插入一行,sql,postgresql,Sql,Postgresql,我有一个这样的表,它是通过稍微修改data+SQL生成的,以按天显示,但我想在右边添加空天数和运行计数 ╔════════════╦════════╦═════════╦════════╗ ║ day ║ num1 ║ num2 ║ tally ║ ╠════════════╬════════╬═════════╬════════╣ ║ 2016-06-10 ║ 9.99 ║ ║ 9.99 ║ ║ 2016-06-12 ║ 136.00 ║
╔════════════╦════════╦═════════╦════════╗
║ 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 ║
╚════════════╩════════╩═════════╩════════╝
╔════════════╦════════╦═════════╦════════╗
║ 白天║ num1║ num2║ 计数║
╠════════════╬════════╬═════════╬════════╣
║ 2016-06-10 ║ 9.99║ ║ 9.99║
║ 2016-06-11 ║ ║ ║ 9.99║ 尝试一下(我假设您的表名为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
尝试一下(我假设您的表名为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
数据:
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)
数据:
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)
数据库是否有一个日历类型的表,每个日期都有一条记录?@DanBracuk是的,这是第一个表,但它只在记录存在时创建一行。我需要一堆空白的日期行,这些行携带理货值,即使该行的所有其他值都为空。数据库是否有一个日历类型的表,其中每个日期都有一条记录?@DanBracuk是的,这是第一个表,但它仅在记录存在时创建一行。我需要一组空白的日期行,这些行将包含理货值,即使该行的所有其他值都为空,但效果很好,谢谢。剩下的唯一问题是获取范围的开始日期和结束日期,我想从发票
表中提取,列开始
有开始日期,列结束
有结束日期。我想找到
start`列的最小值和
end列的最大值,并将其用于范围。编辑,nvm我找到了!虽然我觉得有点复杂,但效果很好,谢谢你。剩下的唯一问题是获取范围的开始日期和结束日期,我想从发票
表中提取,列开始
有开始日期,列结束
有结束日期。我想找到
start`列的最小值和end列的最大值,并将其用于范围。编辑,nvm我找到了!虽然我认为对于我的示例来说,创建表查询有点复杂。OPs和应答者之间的最佳通信方式是以文本格式提供数据结构和样本数据,以便于再现结果和可能的错误。不幸的是,大多数操作人员都没有意识到这一点。是的,我试图搞乱SQLFiddle,结果我搞乱了它半个小时,无法让它工作。有时SQLFiddle确实令人讨厌。感谢为我的示例创建表查询。OPs和应答者之间的最佳通信方式是以文本格式提供数据结构和样本数据,以便于再现结果和可能的错误。不幸的是,大多数操作人员都没有意识到这一点。是的,我试图搞乱SQLFiddle,结果我搞乱了它半个小时,无法让它工作。有时SQLFiddle确实令人讨厌。