Как я могу объединить столбцы из трех таблиц и показать их в одной строке по месяцам? - PullRequest
0 голосов
/ 13 января 2020

У меня есть три таблицы

enter image description here

enter image description here

enter image description here

Я хочу вычесть месячную сумму total_salary из month_salaries, месячную сумму отчислений и ежемесячную сумму от бонусов и показать их на мой взгляд. Я просто не могу понять, как это сделать.

Я попробовал их по отдельности, как показано ниже:

SELECT ANY_VALUE(DATE_FORMAT(date_added, '%m-%Y')), sum(m.total_salary) FROM monthly_salary m GROUP BY month(m.date_added), year(m.date_added);

SELECT ANY_VALUE(DATE_FORMAT(date_added, '%m-%Y')), sum(d.amount) from deductions d GROUP BY month(d.date_added), year(d.date_added);

SELECT ANY_VALUE(DATE_FORMAT(date_added, '%m-%Y')), sum(b.amount) from bonuses b GROUP BY month(b.date_added), year(b.date_added);

Как я могу объединить их, чтобы я мог получать одинаковую сумму зарплат, бонусов и вычетов за один месяц в одном ряду?

Ответы [ 3 ]

2 голосов
/ 13 января 2020

Вы можете выбрать из запросов и присоединиться к ним. Для трех результатов вы хотели бы получить полные внешние объединения для случая, когда в одной из таблиц отсутствует месяц. К сожалению, MySQL не поддерживает полные внешние соединения. Если гарантируется, что в одной таблице никогда не будет месяца, а в другой нет, вы можете просто выполнить внутреннее объединение:

SELECT
  CONCAT(LPAD(mnth, 2, 0), '-', yr),
  s.total AS salary,
  d.total AS deduction,
  b.total AS bonus
FROM
(
  SELECT
    month(date_added) AS mnth,
    year(date_added) AS yr,
    sum(total_salary) AS total
  FROM monthly_salary
  GROUP BY month(date_added), year(date_added);
) s
JOIN
(
  SELECT
    month(date_added) AS mnth,
    year(date_added) AS yr,
    sum(amount) AS total
  FROM deductions
  GROUP BY month(date_added), year(date_added);
) d USING (mnth, yr)
JOIN
(
  SELECT
    month(date_added) AS mnth,
    year(date_added) AS yr,
    sum(amount) AS total
  FROM bonuses
  GROUP BY month(date_added), year(date_added);
) b USING (mnth, yr)
ORDER BY yr, mnth;

Если могут отсутствовать месяцы, сначала выберите все месяцы, а затем оставьте внешнее объединение. вышеуказанные подзапросы:

SELECT
  CONCAT(LPAD(mnth, 2, 0), '-', yr),
  s.total AS salary,
  d.total AS deduction,
  b.total AS bonus
FROM
(
  SELECT month(date_added) AS mnth, year(date_added) AS yr
  FROM monthly_salary
  UNION
  SELECT month(date_added) AS mnth, year(date_added) AS yr
  FROM deductions
  UNION
  SELECT month(date_added) AS mnth, year(date_added) AS yr
  FROM bonuses
) months
LEFT JOIN (...) s USING (mnth, yr)
LEFT JOIN (...) d USING (mnth, yr)
LEFT JOIN (...) b USING (mnth, yr)
ORDER BY yr, mnth;
0 голосов
/ 14 января 2020

Вот что у меня сработало.

Select any_value(Concat(month(m.date_added),'-',year(m.date_added))),any_value(d.deductions), sum(m.total_salary), any_value(b.bonuses) 
from monthly_salary as m 
left join 
(select any_value(date_added) as date_added,sum(amount)
as deductions from deductions group by month(date_added),year(date_added)) as d 
on CONCAT(month(m.date_added),'-',year(m.date_added))=CONCAT(month(d.date_added),'-',year(d.date_added)) 
left join
(select any_value(date_added) as date_added,sum(amount) as bonuses from bonuses group by month(date_added),year(date_added)) as b
on CONCAT(month(m.date_added),'-',year(m.date_added))=CONCAT(month(b.date_added),'-',year(b.date_added)) 
group by month(m.date_added),year(m.date_added);

Однако я не уверен в производительности этого запроса, поэтому я не собираюсь его использовать. Я буду использовать запросы отдельно и объединять их в массив в своем проекте и использовать этот массив.

0 голосов
/ 13 января 2020

Вы можете присоединиться к ним через обычные месяцы:

SELECT ANY_VALUE(DATE_FORMAT(m.date_added, '%m-%Y')), 
       SUM(m.total_salary) AS total_salary,
       SUM(d.amount) AS deductions_amount,
       SUM(b.amount) AS bonuses_amount 
  FROM monthly_salary m
  JOIN deductions d ON month(d.date_added) = month(m.date_added)
  JOIN bonuses b ON month(b.date_added) = month(m.date_added)  
 GROUP BY month(m.date_added), year(m.date_added);
...