简体   繁体   English

MySQL减去两行相似的行并将结果乘以另一行

[英]MySQL subtract two similar rows and multiply results by another row

I want to be able to subtract the qty of ondemand to reserved from the same zone, type and os and then multiply the remaining qty by the rate. 我希望能够从相同区域,类型和os中减去要保留的按需数量,然后将剩余数量乘以比率。

Here is a sample dump of the mysql data 这是mysql数据的示例转储

| Zone  | Type  | Qty | OS    | Reservation | Rate  |
| zone1 | type1 | 12  | linux | ondemand    | 0.24  |
| zone1 | type1 | 6   | linux | reserved    | 0.056 |
| zone1 | type2 | 3   | linux | ondemand    | 0.82  |
| zone2 | type1 | 5   | mswin | ondemand    | 0.24  |
| zone2 | type1 | 2   | mswin | reserved    | 0.056 |
| zone2 | type2 | 3   | linux | ondemand    | 0.82  |
| zone3 | type1 | 4   | linux | ondemand    | 0.24  |
| zone3 | type1 | 1   | linux | reserved    | 0.056 |

The result would be 结果将是

| Zone  | Type  | Qty | OS    | Reservation | Rate  | sum() |
| zone1 | type1 | 6   | linux | ondemand    | 0.24  | 1.44  |
| zone1 | type1 | 6   | linux | reserved    | 0.056 | 0.336 |
| zone1 | type2 | 3   | linux | ondemand    | 0.82  | 0.246 |
| zone2 | type1 | 3   | mswin | ondemand    | 0.24  | 0.72  |
| zone2 | type1 | 2   | mswin | reserved    | 0.056 | 0.112 |
| zone2 | type2 | 3   | linux | ondemand    | 0.82  | 0.246 |
| zone3 | type1 | 3   | linux | ondemand    | 0.24  | 0.72  |
| zone3 | type1 | 1   | linux | reserved    | 0.056 | 0.056 |

I am not sure how to get a distinct statement to work with this. 我不确定如何获得明确的声明来解决这个问题。 I don't know if this is possible with mysql or if I would need to script it and then produce the output. 我不知道这在mysql中是否可行,或者是否需要编写脚本然后生成输出。 Any help is appreciated. 任何帮助表示赞赏。

There isn't always a corresponding reserved in the zone for a type and os that contains an ondemand. 该区域中并不总是为包含ondemand的类型和os保留相应的内容。

You need to join the table to itself: 您需要将表连接到自身:

select
    t1.Zone, t1.Type, t1.Qty - ifnull(t2.Qty, 0), t1.OS,
    t1.rate, (t1.Qty - ifnull(t2.Qty, 0)) * t1.rate as total
from mytable t1
left join mytable t2
    on t1.zone = t2.zone
    and t1.type = t2.type
    and t1.os = t2.os
    and t2.reservation = 'reserved'

and t1.reservation = 'ondemand' 和t1.reservation ='ondemand'

Ihe critical kung fu is the last condition in the join condition. 关键功夫是加入条件中的最后一个条件。 It ensures there is only a join for the "ondemand" rows - with a left join , all other row types (and those "ondenand" rows without a corresponding "reserved" row) will get a null for there join qty value (hence the ifnull() to give them a zero to work with). 它确保“ ondemand”行只有一个联接-带有left join联接时,所有其他行类型(以及那些没有相应“ reserved”行的“ ondenand”行)对于该联接的qty值将为空(因此ifnull()为它们提供零。

Note that this will correctly calculate the total even if there are no matching "reserved" rows for the "ondemand" rows. 请注意,即使“按需”行没有匹配的“保留”行,这也将正确计算总数。

To be honest, I've never seen this kind of query before where only some of the rows from the parent side are joined to, but all rows are kept. 老实说,我以前从未见过这种查询,在这种查询中,只有来自父侧的一些行被连接到了,而所有行都被保留了。

This has not been run, but something like this maybe? 这还没有运行,但是也许是这样?

select zone, type, os, ondemand_cnt, reserved_cnt, ondemand_cnt-reserved_cnt as cnt, 
<some_rate>*(ondemand_cnt-reserved_cnt) as calc_rate
from
(
select zone, type, os, sum(qty) as ondemand_cnt 
from table
where reservation = 'ondemand'
group by zone, type, os
) as o
join
(
select zone, type, os, sum(qty) as reserved_cnt
from table
where reservation = 'reserved'
group by zone, type, os
) as r on (o.zone = r.zone and o.type = r.type and o.os = r.os)

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

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