Sql 按值对有序表中的值更改进行间隔
我有一个使用PostgreSQL的特定任务,我需要一个SQL查询,但不幸的是,我无法得到正确的结果 我的表格示例如下:Sql 按值对有序表中的值更改进行间隔,sql,postgresql,Sql,Postgresql,我有一个使用PostgreSQL的特定任务,我需要一个SQL查询,但不幸的是,我无法得到正确的结果 我的表格示例如下: ---------------------------------------------- | ID | value | usage-date | ---------------------------------------------- | 1 | value1 | 2020-09-10 | --
----------------------------------------------
| ID | value | usage-date |
----------------------------------------------
| 1 | value1 | 2020-09-10 |
----------------------------------------------
| 1 | value1 | 2020-09-15 |
----------------------------------------------
| 1 | value1 | 2020-09-20 |
----------------------------------------------
| 1 | value1 | 2020-09-23 |
----------------------------------------------
| 1 | value1 | 2020-09-25 |
----------------------------------------------
| 1 | value1 | 2020-09-30 |
----------------------------------------------
| 1 | value2 | 2020-09-15 |
----------------------------------------------
| 1 | value2 | 2020-09-20 |
----------------------------------------------
| 1 | value2 | 2020-09-23 |
----------------------------------------------
| 1 | value2 | 2020-09-25 |
----------------------------------------------
因此,表是按ID、值和使用日期排序的。我的任务是提取时间间隔,这些时间间隔应该能够告诉您某个值从哪个日期到哪个日期处于活动状态。因此,输出如下所示:
--------------------------------------------------------------
| ID | value | start-date | end-date |
--------------------------------------------------------------
| 1 | value1 | 2020-09-10 | 2020-09-15 |
--------------------------------------------------------------
| 1 | value2 | 2020-09-15 | 2020-09-20 |
--------------------------------------------------------------
| 1 | value1 | 2020-09-20 | 2020-09-23 |
--------------------------------------------------------------
| 1 | value2 | 2020-09-23 | 2020-09-25 |
--------------------------------------------------------------
| 1 | value1 | 2020-09-25 | 2020-09-30 |
--------------------------------------------------------------
有人知道怎么做吗
这是一个很好的例子,任何人都可以试试。
我猜,您的示例中有两行,一行表示活动的“开始”,另一行表示活动的“结束”。因为您没有显示任何其他标识符,所以查询比必须的复杂。因此,我们首先必须手动删除“end”行
SELECT
id,
value,
usagedate,
COALESCE( -- 4
lead(usagedate) OVER (PARTITION BY id ORDER BY usagedate), -- 3
first_value -- 4
)
FROM (
SELECT
*,
row_number() OVER (PARTITION BY id, value ORDER BY usagedate), -- 1
first_value(usagedate) OVER (PARTITION BY id ORDER BY usagedate DESC) -- 2
FROM
t
)s
WHERE row_number % 2 = 1 -- 1
WHERE
子句),我们可以使用lead()
窗口函数将每个已排序的下一行的值转换为当前行。因此,我们可以使用每个新活动的开始日期作为当前活动的结束日期。这就是为什么实际上您不需要“end”行,而我们删除了它们lead()
函数返回NULL
。为了避免这种情况,我们先前获取了最后一条记录(最后一个活动的结束)。使用COALESCE()
函数可以实现这一点。它接受其参数列表中的第一个非空值,如果不是最后一个,则为lead
值,如果是first\u值
您的输入与预期的输出不一致,在预期的日期范围内,值1和值2之间没有明显的区别,似乎您只是想强制输出 回答:如果您希望该值的日期范围接近,可以使用以下查询,而不是为每个值创建多个条目:
select distinct one1.id, vals.value1, one.minn as start_date, two.maxx as end_date from
table one1 inner join
(select value1 vals, min(user_date) as minn from table group by value1) one
on
one1.value = one.vals
inner join (
select value1 valm, max(user_date) as maxx from table group by value1) two
on one.vals = two.valm