简体   繁体   中英

How to create new column based on other column's values in MySQL

EDIT

I tried this solution(below answer) to solve this problem.

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

This solution works. But execution - fetching time are the 30 - 5 seconds in mysql.

Bu when I try this solution(same above but different version. or am i wrong?);

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)

With above query, execution - fetching time are 5 - 30 seconds. Why??


I have a table X like this;

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

As you can see x_val column value can only be 0 or 1 . But I want to create new column based on other columns. All values partitioned by id .

I want output table like this;

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 ...
...

In above table, global_e is created based on id and timestamp . If x_val is 1, that means global_e must be equal to the id + current row timestamp . If it is 0, global_e must be equal to the previous value.

How can I create global_e column like above?

In MySQL 8+, you can use a cumulative max. This is basically:

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

This is not quite what you want, because you want the minimum, when there is no row with 1 . So, use 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;

In earlier versions, a correlated subquery is probably the simplest approach:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM