СОЕДИНЕНИЕ двух таблиц ГДЕ и СУММА - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть эта таблица с названием sales:

vat,    activation
12345   2017-07-28
567892  2018-08-21
224124  2016-08-22

и эта таблица с именем invoices:

cif,   billdate,    amount
12345  2017-07-19   200
12345  2017-07-29   250
12345  2017-08-02   3000
224124 2016-08-24   400
224124 2018-09-08   2499

Я хочу получить такую ​​таблицу:

vat,   activation, first_month_amount
12345  2017-07-28  450
224124 2016-08-22  400
567892 2018-08-21  200

В основном сумма всех счетов, выставленных за месяц активации.

До сих пор я пытался это сделать:

select * from  sales
LEFT JOIN ( 
    SELECT vat,sum(amount) as first_month_amount
    FROM invoices 
    WHERE month(billdate)=month(activation) 
    Group by cif
    ) as salesdata on sales.vat = salesdata.cif 

Запрос не выполнен, поскольку не удалось найти столбец активации.

Вторая попытка была:

select * from  sales
LEFT JOIN ( 
    SELECT vat,sum(amount) as first_month_amount
    FROM invoices 
    WHERE month(billdate)=month(activation) 
    Group by cif
    ) as salesdata on sales.vat = salesdata.cif 

Сбой снова, потому что он не может найти столбец billdate

Как это можно сделать?

Ответы [ 4 ]

0 голосов
/ 25 сентября 2019

Вы можете просто сделать объединение между таблицами:

select s.vat, s.activation, sum(i.amount)
from sales s
 left join invoices i on last_day(i.billdate)=last_day(s.activation)
group by s.vat, s.activation;

SQLFiddle

Не уверен в логике последней ожидаемой строки (567892 2018-08-21 200) поскольку данных для этого нет.

0 голосов
/ 25 сентября 2019

Этот запрос даст вам желаемые результаты.Он группирует продажи по годам и месяцам, а также cif и создает значения JOIN для года-месяца и значения cif:

SELECT s.vat, s.activation, COALESCE(i.amount, 0) AS amount
FROM sales s
LEFT JOIN (SELECT cif, DATE_FORMAT(billdate, '%Y%m') AS billmonth, SUM(amount) AS amount
           FROM invoices
           GROUP BY cif, billmonth) i ON i.cif = s.vat AND i.billmonth = DATE_FORMAT(s.activation, '%Y%m')

Вывод (обратите внимание, значение 0 для vat = 567892, посколькунет данных в invoices):

vat     activation  amount
12345   2017-07-28  450
567892  2018-08-21  0
224124  2016-08-22  400

Демонстрация на dbfiddle

0 голосов
/ 25 сентября 2019

Вы можете попробовать ниже -

select vat, activation,first_month_amount
from sales s
(
SELECT cif,month(billdate) mbill,year(billdate) ybill,sum(amount) as first_month_amount
    FROM invoices 
    Group by cif,month(billdate),year(billdate)
)s1 on s.vat=s1.cif and month(activation)=mbill and year(activation)=ybill
0 голосов
/ 25 сентября 2019

Один из способов - использовать Коррелированный подзапрос ;Кроме того, просто сопоставление месяцев недостаточно, вам также нужно будет сопоставить год, чтобы правильно получить сумму «первого месяца»:

select s.*, 
       (select sum(i.amount) 
        from invoices i 
        where month(i.billdate) = month(s.activation) 
              and year(i.billdate) = year(s.activation) 
              and i.cif = s.vat
       ) first_month_amount
from  sales s 

Приведенный выше запрос может быть исполнителем , имеяиндекс (cif) на invoices таблице.Итак, если вы еще не определили этот индекс;Вы можете использовать следующее:

ALTER TABLE invoices ADD INDEX (cif);

Но этот запрос все еще недостаточно оптимизирован (по крайней мере, как по мне).В настоящее время использование функций Month() и Year() в значении даты запрещает использование индекса в поле billdate таблицы invoices.

Таким образом, мы можем сделать запрос sargeable следующим образом:

select s.*, 
       (select sum(i.amount) 
        from invoices i 
        where i.cif = s.vat 
              and i.billdate 
                    between date_format(s.activation, '%Y-%m-01') 
                            and last_day(s.activation)
       ) first_month_amount
from  sales s 

Этот запрос будет достаточно быстрым , если мы определим следующий составной индекс для таблицы invoices.Обратите внимание, что billdate должен стоять в конце индекса, так как это условие диапазона:

ALTER TABLE invoices ADD INDEX (cif, billdate);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...