Моя таблица Postgresql выглядит так:
CREATE TABLE foo(man_id, subgroup, power, grp)
AS VALUES
(1, 'Sub_A', 4, 'Group_A'),
(2, 'Sub_B', -1, 'Group_A'),
(3, 'Sub_A', -1, 'Group_B'),
(4, 'Sub_B', 6, 'Group_B'),
(5, 'Sub_A', 5, 'Group_A'),
(6, 'Sub_B', 1, 'Group_A'),
(7, 'Sub_A', -1, 'Group_B'),
(8, 'Sub_B', 2, 'Group_B'),
(9, 'Sub_C', 2, 'Group_B');
Расчет мощности работает следующим образом:
Total Power of Subgroup Sub_A in the grp Group_A is (4 + 5 ) = 9
Total Power of Subgroup Sub_B in the grp Group_A is ((-1) + 1 ) = 0
Total Power of Subgroup Sub_A in the grp Group_B is ((-1) + (-1) ) = -2
Total Power of Subgroup Sub_B in the grp Group_B is (6 + 2 ) = 8
So the power of Sub_A in the Group_A is not equal to power of Sub_A in the Group_B
So the power of Sub_B in the Group_A is not equal to power of Sub_B in the Group_B
Я могу запросить базу данных и получить данные, где для одного и того же имени subgroup
общая power
не равна всем другим именам grp
.
SELECT f.*
FROM (
SELECT subgroup
FROM (
SELECT subgroup, grp, sum(power) AS total_power
FROM foo
GROUP BY subgroup, grp
) sub
GROUP BY 1
HAVING min(total_power) <> max(total_power)
) sg
JOIN foo f USING (subgroup);
Я также хочу сделать значение суммы одинаковым. Для одного и того же имени subgroup
общая power
должна быть равна всем другим именам grp
.
Мы можем получить записи, в которых сумма не равна указанному выше запросу. Затем мы можем найти разницу sum(power)
значения и добавить это значение разности в power
любой subgroup
где power
меньше при этом grp
.
Решение MySQL также будет принято.
Вышеприведенный запрос вернет эти данные, потому что для одной и той же subgroup
общая power
не равна поперек grp
s,
(1, 'Sub_A', 4, 'Group_A')
(5, 'Sub_A', 5, 'Group_A')
(3, 'Sub_A', -1, 'Group_B')
(7, 'Sub_A', -1, 'Group_B')
(2, 'Sub_B', -1, 'Group_A')
(6, 'Sub_B', 1, 'Group_A')
(4, 'Sub_B', 6, 'Group_B')
(8, 'Sub_B', 2, 'Group_B')
Теперь я хочу изменить значения мощности, чтобы сделать сумму идентичной,
Например, для общей разности мощности Sub_A между Group_A и Group_B (9- (-1 -1)) = 11, поэтому мы добавим 11 в любое значение мощности Sub_A в группе Group_B, допустим, мы модифицируем эту запись,
(3, 'Sub_A', -1, 'Group_B')
преобразованный в (3, 'Sub_A', 10, 'Group_B')
То же самое мы будем делать и для других, где бы не было несбалансированного.
Ниже запроса будет получен желаемый результат
with foo(man_id, subgroup, power, grp) as ( select * from ( VALUES (1, 'Sub_A', 4, 'Group_A'), (2, 'Sub_B', -1, 'Group_A'), (3, 'Sub_A', -1, 'Group_B'), (4, 'Sub_B', 6, 'Group_B'), (5, 'Sub_A', 5, 'Group_A'), (6, 'Sub_B', 1, 'Group_A'), (7, 'Sub_A', -1, 'Group_B'), (8, 'Sub_B', 2, 'Group_B'), (9, 'Sub_C', 2, 'Group_B') ) as x(man_id, subgroup, power, grp) ), sub_per_group as ( select subgroup, grp, sum(power) tot_per_grp from foo group by subgroup,grp ), sub_calc as ( select subgroup, max(tot_per_grp) as max, json_agg( json_build_object( 'grp',grp, 'tot_per_grp',tot_per_grp ) ) as grps_tot from sub_per_group group by subgroup having count(distinct tot_per_grp)!=1 ) select f.man_id,f.subgroup, case when rn=1 then ( power+ ( coalesce(max,0)- coalesce(( select (v->>'tot_per_grp')::int from json_array_elements(grps_tot) as v where (v->>'grp')::text =f.grp),0) ) ) else power end, f.grp from sub_calc sc right join ( select row_number() over(partition by subgroup,grp) as rn, foo.* from foo ) f on f.subgroup=sc.subgroup and f.rn=1 order by subgroup,grp