我有一个复杂的SQL问题。
我们可以在选择查询中更新列吗?示例:
考虑此表:
|ID |SeenAt |
----------------
|1 |20 |
|1 |21 |
|1 |22 |
|2 |70 |
|2 |80 |
我想要第一次看到每个ID时给出每个ID的选择查询。它何时看到"再次":
|ID |Start |End |
---------------------
|1 |20 |21 |
|1 |20 |22 |
|1 |20 |22 |
|2 |70 |80 |
|2 |70 |80 |
首先,这两个列Start
和End
都具有相同的值,但是当看到具有相同ID
的第二行我们需要更新其前身以使End
为CC_4提供新的SeenAt
值。我成功地创建了Start
列,我将每个ID
的最小 SeenAt
值给所有ID。但是我找不到每次更新End
列的方法。
不要介意双打,我还有其他列会在每一行中改变
另外,我在Impala工作,但可以使用Oracle。
我希望我已经足够清楚了。谢谢
您可以使用lead()
和nvl()
:
select id, min(seenat) over (partition by id) seen_start,
nvl(lead(seenat) over (partition by id order by seenat), seenat) seen_end
from t
demo
启动很容易,只有 GROUP
MIN
结束您需要在SeenAt
之后找到最小
SQL演示
SELECT "ID",
(SELECT MIN("SeenAt")
FROM Table1 t2
WHERE t1."ID" = t2."ID") as "Start",
COALESCE(
(SELECT MIN("SeenAt")
FROM Table1 t2
WHERE t1."ID" = t2."ID"
AND t1."SeenAt" < t2."SeenAt")
, t1."SeenAt"
) as End
FROM Table1 t1
输出
| ID | START | END |
|----|-------|-----|
| 1 | 20 | 21 |
| 1 | 20 | 22 |
| 1 | 20 | 22 |
| 2 | 70 | 80 |
| 2 | 70 | 80 |
您似乎需要使用self-join
的min()
分析功能:
select distinct t1.ID,
min(t1.SeenAt) over (partition by t1.ID order by t1.ID) as "Start",
t2.SeenAt as "End"
from tab t1
join tab t2 on t1.ID=t2.ID and t1.SeenAt<=t2.SeenAt
order by t2.SeenAt;
demo