#mysql #sql
#mysql #sql
Вопрос:
У меня есть следующие данные,
Id Value Tag
1 200 C
1 300 D
1 100 D
2 300 D
2 100 D
Я хочу суммировать значения тегов и вычесть сумму D из суммы C. Приведенное ниже работает нормально, если для идентификатора присутствуют оба тега.
SELECT
D.sumOfD - C.sumOfC as value,
FROM (
SELECT IFNULL(ROUND(SUM(value),2),0) as 'sumOfD',Id
FROM Reports exp WHERE exp.tag = 'D'
) as D
JOIN (
SELECT IFNULL(ROUND(SUM(value),2),0) as 'sumOfC' ,Id
FROM Reports exp WHERE exp.tag = 'C'
) as C ON C.Id = D.Id
;
Но если тег недоступен для идентификатора, ни один из подзапросов не вернет значение. В приведенном выше примере данных есть только тег D для идентификатора 2, поэтому on C.Id = D.Id
условие не выполняется. В этом случае я хочу, чтобы возвращался ноль.
Ожидаемый результат
Id Value
1 200 (300 100-200)
2 400 (300 100-0) -- where 0 is the sum of values for tag C for id 2 which is zero
Как я могу это сделать? Я использую mysql 8.0.17
Комментарии:
1. Укажите также ожидаемый результат.
Ответ №1:
Попробуйте следующее — используя conditional aggregation
select id,
sum(case when Tag='D' then value else 0 end)-sum(case when Tag='C' then value else 0 end) as diff
from tablename
group by id
Комментарии:
1. Я отредактировал свой вопрос, чтобы включить желаемый результат.
2. @Ayubx, этот ответ должен удовлетворить ваш желаемый результат
Ответ №2:
Использование условной агрегации, предложенной Фахми, — отличная идея, вот запрос:
SELECT sums.D - sums.C as value
FROM (SELECT SUM(IF(tag = 'C', value, 0)) as C,
SUM(IF(tag = 'D', value, 0)) as D
FROM Reports
GROUP BY id
) AS sums
Хитрость заключается в использовании GROUP BY
предложения в вашем id, чтобы легко суммировать ваши значения, и условной агрегации для обоих тегов, чтобы получить их в отдельных значениях.
Ответ №3:
Я думаю, что самый простой метод:
select id,
sum(case when Tag = 'D' then value
when Tag = 'C' then - value
else 0
end) as diff
from tablename
group by id