СУММ () в где - Mysql - PullRequest
       90

СУММ () в где - Mysql

0 голосов
/ 16 июня 2020

Запрос ниже показывает результаты контракта, задержка контракта которого составляет between 1 and 487 days.

Теперь я хочу добавить значения счетов-фактур, принадлежащих контракту invoice.value, а затем отфильтровать по баланс контракта, сумма которого находится между одним значением и другим.

В этом случае у меня было бы 8 результатов, которые соответствовали бы приведенному ниже запросу, с балансом контракта between 4 and 5 dolars and delay between 1 and 487 days, но я получаю только 1 результат, но неверный.

Что я делаю не так?

tb_contract

id
contract

tb_invoice

id
contract_id
value
due_date

Запрос

SELECT DISTINCT `contract`.*
FROM `tb_contract` `contract`
LEFT JOIN `tb_invoice` `invoice` ON `invoice`.`contract_id` = `contract`.`id`
WHERE `contract`.`creditor_id` = '5ddf5246-fed4-4e5f-538d-34df1e8cf9ee'
AND DATEDIFF(CURDATE(), invoice.due_date) >= 1
AND DATEDIFF(CURDATE(), invoice.due_date) <= 487
GROUP BY `contract`
HAVING SUM(invoice.value) between 4.00 AND 5.00

enter image description here

без использования Haveing ​​и использования where invoice.value, Я получаю контракт, в котором есть как минимум 1 счет-фактура, который соответствует параметрам значений, однако он содержит другие счета-фактуры из того же контракта, которые содержат несколько других значений выше параметров консультации. Я хочу добавить все счета-фактуры контракта и фильтровать только между параметрами значений. Другими словами, сложение всех счетов-фактур по контракту не может быть меньше или больше, чем суммы

Это будет другой запрос

SELECT DISTINCT `contract`.*
FROM `tb_contract` `contract` LEFT JOIN `tb_invoice` `invoice` ON `invoice`.`contract_id` = `contract`.`id`
WHERE `contract`.`creditor_id` = '5ddf5246-fed4-4e5f-538d-34df1e8cf9ee'
AND `invoice`.`value` between 4.00 AND 5.00
AND DATEDIFF(CURDATE(), invoice.due_date) >= 1
AND DATEDIFF(CURDATE(), invoice.due_date) <= 487

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

Я с подозрением отношусь к предложению group by: является ли contract фактическим столбцом в какой-либо таблице, которая участвует в запросе? Чтобы ваш запрос был действительным SQL, он должен быть первичным ключом таблицы контрактов.

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

В целом, я думаю, что это было бы проще и эффективнее выразить путем объединения таблицы контрактов с агрегированным подзапросом в счетах-фактурах:

select c.*, i.total_value
from tb_contract contract c
inner join (
    select contract_id, sum(value) total_value
    from tb_invoice
    group by contract_id
    having 
        max(i.due_date) >= current_date - interval 487 day
        and min(i.due_date) < current_date
        and sum(value) >= 4 
        and sum(value) <  5
) i on i.contract_id = c.id
where c.creditor_id = '5ddf5246-fed4-4e5f-538d-34df1e8cf9ee'
0 голосов
/ 16 июня 2020
SELECT `contract`.*,SUM(invoice.value) AS inv_tot
FROM `tb_contract` `contract`
LEFT JOIN `tb_invoice` `invoice` ON `invoice`.`contract_id` = `contract`.`id`
WHERE `contract`.`creditor_id` = '5ddf5246-fed4-4e5f-538d-34df1e8cf9ee'
AND DATEDIFF(CURDATE(), invoice.due_date) >= 1
AND DATEDIFF(CURDATE(), invoice.due_date) <= 487
GROUP BY `contract`
HAVING inv_tot between 4.00 AND 5.00
...