更新 SELECT 查询中的列值

Update a column value within a SELECT query

我有一个复杂的 SQL 问题。

我们可以更新 SELECT 查询中的列吗?示例:

考虑这个 table:

    |ID   |SeenAt  |
    ----------------
    |1    |20      |
    |1    |21      |
    |1    |22      |
    |2    |70      |
    |2    |80      |

我想要一个 SELECT 查询,为每个 ID 提供首次看到的时间。什么时候看到的 'again':

    |ID   |Start  |End  |
    ---------------------
    |1    |20     |21   |
    |1    |20     |22   |
    |1    |20     |22   |
    |2    |70     |80   |
    |2    |70     |80   |

首先,StartEnd 两列都具有相同的值,但是当看到具有相同 ID 的第二行时,我们需要更新其前身以提供 End 新的 SeenAt 值。 我成功创建了 Start 列,我将每个 ID 的最小值 SeenAt 赋予所有 ID。但是我找不到每次都更新 End 列的方法。

不要介意双打,我还有其他列在每个新行中都会发生变化

此外,我在 Impala 工作,但我可以使用 Oracle。

我希望我已经足够清楚了。谢谢

开始很容易只是 MINGROUP

结束你需要在 SeenAt 之后找到 MIN,如果你没有找到它那么当前的 SeenAt

SQL DEMO

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 |

您似乎需要 min() 具有 self-join:

的分析函数
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

您可以使用 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