如何在MySQL中基于其他列的值创建新列

时间:2019-09-02 12:27:08

标签: mysql sql

编辑

我尝试了此解决方案(下面的答案)来解决此问题。

select timestamp, id, coalesce(
        max(case when val = 1 then unix_timestamp(timestamp) end) over (partition by idorder by timestamp),
        min(unix_timestamp(timestamp)) over (partition by id)
    )) as global_e
from table

此解决方案有效。但是执行-获取时间是mysql中的30-5秒。

Bu,当我尝试此解决方案时(与上面相同,但版本不同。或者我错了吗?);

select timestamp, id, coalesce(
            max(case when val = 1 then unix_timestamp(timestamp) end) over prt,
            min(unix_timestamp(timestamp)) over prt        
       )) as global_e
from table 
window as prt (partition by id order by timestamp)

通过上述查询,执行-提取时间为5-30秒。为什么?


我有一个这样的表X

id       timestamp       x_val
1          ts1            0
1          ts2            0
1          ts3            1
1          ts4            0
1          ts5            1 
2 ...
...

如您所见,x_val列值只能是0 or 1。但是我想基于其他列创建新列。所有值均按id进行分区。

我想要这样的输出表;

id       timestamp       x_val    global_e
1          ts1            0         1_ts1
1          ts2            0         1_ts1
1          ts3            1         1_ts3
1          ts4            0         1_ts3
1          ts5            1         1_ts5
2 ...
...

在上表中,基于global_e创建了id and timestamp。如果x_val为1,则表示global_e必须等于id + current row timestamp。如果为0,则global_e必须等于先前的值。

如何创建如上所述的global_e列?

1 个答案:

答案 0 :(得分:1)

在MySQL 8+中,您可以使用累积最大值。基本上是这样:

select x.*,
       max(case when x_val = 1 then timestamp end) over (partition by id order by timestamp) as global_e
from x;

这不是您想要的,因为当1没有行时,您需要的是最小值。因此,请使用coalesce()

select x.*,
       coalesce(max(case when x_val = 1 then timestamp end) over (partition by id order by timestamp),
                min(timestamp) over (partition by id)
               ) as global_e
from x;

在早期版本中,关联子查询可能是最简单的方法:

select x.*,
       (select coalesce(max(case when x2.x_val = 1 then timestamp end), min(timestamp)
        from x x2
        where x2.id = x.id and 
              x2.timestamp <= x.timestamp
       ) as global_e
from x;