MySQL: СУММА столбца на основе значения другого столбца

Я хочу иметь сумму столбца, основанную на том, что значение другого столбца равно этому/этому. Вот моя структура таблицы

id  leave_hours leave_type overtime_hours employee_id
1     7.6          1           0               3
2      5           2           0               3
3      0           0           2.3             3

У меня уже есть этот запрос, но мне нужен столбец, который будет суммироваться только в том случае, если тип выхода равен 1 и если тип выхода равен 2.

SELECT employee_id, SUM(overtime_hours) AS ot_hrs, SUM(leave_hours if leave_type == 1) AS  
       leave_1, SUM(leave_hours if leave_type == 2) AS leave_2
FROM table
GROUP BY employee_id

Результат должен быть:

employee_id  ot_hrs leave_1  leave_2
    3          2.3    7.6       5

Спасибо за ваш вклад.

Что вы хотите подытожить?

Nick 31.05.2019 05:22

Вашего описания недостаточно, чтобы предложить лучшее решение.

Blasanka 31.05.2019 05:23

отредактировал вопрос, чтобы отразить результат и запрос суммы.

Ronald 31.05.2019 05:25
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
4
3
807
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам нужно использовать условную агрегацию, чтобы суммировать разные leave_hours по отдельности:

SELECT employee_id, 
       SUM(overtime_hours) AS ot, 
       SUM(CASE WHEN leave_type = 1 THEN leave_hours ELSE 0 END) AS leave_1, 
       SUM(CASE WHEN leave_type = 2 THEN leave_hours ELSE 0 END) AS leave_2
FROM `table`
GROUP BY employee_id

Выход:

employee_id ot      leave_1     leave_2
3           2.3     7.6         5

Демо на dbfiddle

Обратите внимание, что если вы используете числа с плавающей запятой для хранения часов, вам может потребоваться ROUND результаты.

При этом лучше использовать NULL вместо 0. Таким образом, у вас не будет существования какой-либо записи, которую вы считаете не, измените результат с NULL на 0.

ysth 31.05.2019 05:29

не нужен круглый, но этот работает. просто отредактируйте его без раунда, и я поставлю это как принятый ответ.

Ronald 31.05.2019 05:30

Демо на dbfiddle использует FLOAT для чисел, а 2.3 и 7.6 не могут быть точно представлены как числа с плавающей запятой. Поэтому я округляю их, а не показываю 2.29999999837424 и т. д.

Nick 31.05.2019 05:30

@Ronald ROUNDing удален.

Nick 31.05.2019 05:32

Ах. В большинстве случаев лучше использовать десятичное число, а не число с плавающей запятой.

ysth 31.05.2019 05:33

@ysth действительно. Режим db-fiddle по умолчанию, когда вы просто вводите данные таблицы, всегда выбирает FLOAT, мне просто нужно не забыть изменить его...

Nick 31.05.2019 05:37

вы можете использовать max() с случаем, когда

SELECT employee_id, 
       max(overtime_hours) AS ot, 
       max(CASE WHEN leave_type = 1 THEN leave_hours  END) AS leave_1, 
       max(CASE WHEN leave_type = 2 THEN leave_hours END) AS leave_2
FROM  table_name
GROUP BY employee_id

выход

employee_id     ot     leave_1       leave_2
3              2.3  7.599999904632568   5

Могу ли я узнать причину использования MAX?

Ronald 31.05.2019 05:38

@Ronald, вам нужен поворот, который можно легко сделать с помощью max() db-fiddle.com/f/pNw42Q4yRiMhA7qFGTEZ4R/2

Zaynul Abadin Tuhin 31.05.2019 05:40

@ Рональд, я предполагаю, потому что в ваших данных показана только одна запись для leave_type/employee; max тогда будет эквивалентно сумме. Но я предполагаю, что у вас может быть больше одного.

ysth 31.05.2019 09:27

Другие вопросы по теме