Запрос двух несбалансированных таблиц - PullRequest
1 голос
/ 21 июня 2019

Сумма по двум таблицам возвращает нежелательную сумму из одной таблицы, умноженную на количество строк в другой

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

Table 1(Actual)

Date        Location   Amount
01/01/2019  Loc1       1000 
01/02/2019  Loc1       700
01/01/2019  Loc2       7500
01/02/2019  Loc2       1000
02/01/2019  Loc1       500

Table 2(Plan)

Year   Month       Location   Amount
2019   1           Loc1       1500
2019   1           Loc2       8000
2019   2           Loc1       800

Я пробовал разные соединения, используя YEAR (Table1.date) и Month (table1.date) и группируя по Месяц (Table1.Date), но я продолжаю сталкиваться с той же проблемой, когда PlanAmount умножается на сколько строк в фактической таблице ...

в примере loc1 для месяца 1 ниже я получаю

Year Month Location PlanAmount  ActualAmount
2019 1     Loc1     3000        1700

Я хотел бы вернуть ниже

Year Month Location PlanAmount  ActualAmount
2019 1     Loc1     1500        1700
2019 1     Loc2     8000        8500
2019 2     Loc1     800         500

Заранее спасибо за любую помощь D

Ответы [ 4 ]

1 голос
/ 21 июня 2019

Мне кажется, проблема в том, что вы используете sum(PlanTable.Amount) при группировке.Попробуйте использовать max(PlanTable.Amount).

select 
    p.Year,
    p.Month,
    p.Location,
    sum(a.Amount) as actual_amount,
    max(p.Amount) as plan_amount
from 
    [Plan] p left join Actual a 
        on year(a.date) = p.year
        and month(a.date) = p.Month 
        and a.Location = p.Location
group by 
    p.year,
    p.month,
    p.Location

SQL Fiddle

1 голос
/ 21 июня 2019

Вы можете сделать это с full join или union all / group by:

select yyyy, mm, location,
       sum(actual_amount) as actual_amount,
       sum(plan_amount) as plan_amount
from ((select year(date) as yyyy, month(date) as mm, location,
              amount as actual_amount, 0 as plan_amount
       from actual
       group by year(date) as yyyy, month(date) as mm, location
      ) union all
      (select year, month, location,
              0 as actual_amount, amount as plan_amount
       from actual
       group by year, month, location
      )
     ) ap
group by yyyy, mm, location;

Это гарантирует, что у вас есть строки, даже если в другой таблице нет совпадений.

1 голос
/ 21 июня 2019

Чтобы получить требуемые результаты, вам нужно сгруппировать первую таблицу по году, дате, месяцу и месту и выбрать столбцы год, месяц, местоположение и сумму в группе, после чего вам нужно присоединиться к этому результату.r

SELECT 
   plans.year, 
   plans.month, 
   plans.location, 
   plans.plan_amount, 
   grouped_results.actual_amount 
FROM plans 
INNER JOIN (
    SELECT 
        datepart(year, date) AS year, 
        datepart(month, date) AS month, 
        location, 
        SUM(amount) AS actual_amount 
    FROM actuals 
    GROUP BY datepart(year, date), datepart(month, date), location
) as grouped_results
ON 
    grouped_results.year = plans.year AND 
    grouped_results.month = plans.month AND 
    grouped_results.location = plans.location
0 голосов
/ 21 июня 2019

получает год и месяц от даты и использует их в соединении, большинство dbms имеет функции года и месяца, которые вы можете использовать в соответствии с вашей СУБД

select year(t1.date) yr,month(t1.date) as monthofyr ,t1.Location,
sum(t1.amount) as actual_amoun,
sum(t2.amount) as planamount
from table1 t1 left join table2 t2 on
month(t1.date)= t2.Month and t1.Location=t2.Location
and year(t1.date)=t2.year
group by year(t1.date) ,month(t1.date),Location
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...