简体   繁体   English

SQL 查询:根据其他列给列加值

[英]SQL Query : Add values to columns based on other columns

I have a dataset which looks like this:我有一个如下所示的数据集:

Part          Runs          Duration          Date
-------------------------------------------------------
random_1       NULL          20              2020-01-01           
random_2       NULL          1               2020-01-01            
random_3       NULL          4               2020-01-01           
tot_rand       40            NULL            2020-01-01           
random_1       NULL          60              2020-01-02           
random_2       NULL          12              2020-01-02            
random_3       NULL          3               2020-01-02           
tot_rand       100           NULL            2020-01-02           
random_1       NULL          9               2020-01-10           
random_2       NULL          4               2020-01-10            
tot_rand       30            NULL            2020-01-10           

Now instead of NULL values in column Runs I want to add the tot_rand value for the same Date .现在,而不是 NULL 列中的值Runs我想为相同的Date添加tot_rand值。

So that the result will look like this:这样结果将如下所示:

Part          Runs          Duration          Date     
-------------------------------------------------------
random_1       40           20              2020-01-01           
random_2       40           1               2020-01-01            
random_3       40           4               2020-01-01           
tot_rand       40           NULL            2020-01-01           
random_1       100          60              2020-01-02           
random_2       100          12              2020-01-02            
random_3       100          3               2020-01-02           
tot_rand       100          NULL            2020-01-02           
random_1       30           9               2020-01-10           
random_2       30           4               2020-01-10            
tot_rand       30           NULL            2020-01-10   

The reason for this is that in the end I want to create a new column called All which will count:这样做的原因是,最后我想创建一个名为All的新列,它将计算在内:

(Runs - Duration) / Runs

Final result最后结果

Part          Runs          Duration          Date           All
---------------------------------------------------------------------
random_1       40           20              2020-01-01       0.5
random_2       40           1               2020-01-01       0.975     
random_3       40           4               2020-01-01       0.9    
tot_rand       40           NULL            2020-01-01       NULL    
random_1       100          60              2020-01-02       0.4  
random_2       100          12              2020-01-02       0.88    
random_3       100          3               2020-01-02       0.97    
tot_rand       100          NULL            2020-01-02       NULL    
random_1       30           9               2020-01-10       0.7    
random_2       30           4               2020-01-10       0.86     
tot_rand       30           NULL            2020-01-10       NULL

I'm working in MariaDB / MySQL environment.我在 MariaDB / MySQL 环境中工作。

Maybe there is some other way to do this?也许还有其他方法可以做到这一点? I'm all open for suggestions.我愿意接受建议。

SELECT t1.Part, t2.Runs, t1.Duration, `Date`, 1 - t1.Duration / t2.Runs `All`
FROM test t1
JOIN test t2 USING (`Date`)
WHERE t2.Part = 'tot_rand'

Only one row for each Date value must contain Part = 'tot_rand' .每个Date值只有一行必须包含Part = 'tot_rand'

The value of Runs will be replaced even if it is not NULL.即使不是 NULL, Runs的值也会被替换。 Or you may use original t1.Runs but t2.Runs or COALESCE(t1.Runs, t2.Runs) in All calculation.或者您可以在All计算中使用原始t1.Runst2.RunsCOALESCE(t1.Runs, t2.Runs)

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=440969fc417980aa3688bb4dac67bab2 https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=440969fc417980aa3688bb4dac67bab2

You can use window functions:您可以使用 window 函数:

select t.*,
       coalesce(runs, max(runs) over (partition by date)) as imputed_runs
from t;

If you specifically wanted the 'tot_rand' value, you can use conditional aggregation:如果您特别想要'tot_rand'值,可以使用条件聚合:

select t.*,
       coalesce(runs,
                 max(case when part = 'tot_rand' then runs end) over (partition by date)
               ) as imputed_runs
from t;

If you wanted an update , then one approach is:如果您想要update ,那么一种方法是:

update t join
       (select date, max(runs) as max_runs
        from t
        where part = 'tot_rand'
        group by date
       ) tt
       on t.date = tt.date
    set runs = tt.max_runs
    where tt.runs is null;

The subquery may not require aggregation, but it is unclear if there can be more than on 'tot_rand' value on a given date.子查询可能不需要聚合,但不清楚在给定日期是否可以有超过 on 'tot_rand'值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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