Интересно, можно ли удалить результаты с тем же значением?
У меня есть таблица платежей, содержащая КОРРЕКТИРОВКИ и ВОЗВРАТЫ, введенные как AJUSTE и ESTORNO. Хотя оба могут существовать в счете, если общая сумма каждого из них равна, их следует игнорировать. Если суммы каждого из них не равны, то они будут учитываться при расчете.
Я составил список каждого из них следующим образом:
select sum(pay_amount) as pay_amount, pay_type, pay_date, active, invoice_no, invoice_date
from payments
where pay_type = 'AJUSTE'
and pay_date like '%-%-2024'
and active = '1'
and pay_amount not in (
select SUM(pay_amount) as pay_amount
from payments
where pay_type = 'ESTORNO' and pay_date like '%-%-2024' and active = '1'
group by invoice_no
)
GROUP BY invoice_no;
Тогда этот запрос на противоположное:
select sum(pay_amount) as pay_amount, pay_type, pay_date, active, invoice_no, invoice_date
from payments
where pay_type = 'ESTORNO'
and pay_date like '%-%-2024'
and active = '1'
and pay_amount not in (
select SUM(pay_amount) as pay_amount
from payments
where pay_type = 'AJUSTE' and pay_date like '%-%-2024' and active = '1'
group by invoice_no
)
GROUP BY invoice_no;
Несмотря на то, что возвраты являются отрицательными, я хочу исключить все одинаковые суммы и добавить разные.
Возможно ли это с помощью запроса в MySQL 5.7?
---- редактировать ------
Я создал скрипт с демонстрационными данными: https://www.mycompiler.io/view/6qxcOxSlkuv
AJUSTE (Корректировки) — это положительные числа в БД, тогда как ESTORNO (возвраты) — это отрицательные суммы.
При возврате средств должна последовать корректировка на ту же сумму, чтобы обнулить остаток в счете. Существуют сценарии, когда корректировка может существовать без возврата средств, когда клиент не выплачивает полный баланс, не исправляет ошибку и т. д. В этом случае нам необходимо знать pay_amount и pay_type этой корректировки.
Также возможно, что корректировок может быть 2, а возврат только 1. Бывший. Клиент оплатил половину остатка, и эта половина платежа была возмещена, а также полная корректировка списания счета.
Запрос должен рассматривать каждый отдельный счет-фактуру. Когда сумма всех возвратов и корректировок в одном счете существует и равна нулю, мы пропускаем этот конкретный счет. Если сумма корректировки превышает сумму возврата или наоборот, нам нужен pay_type (AJUSTE или ESTORNO) с разницей (pay_type). (например, ESTORNO 100, AJUSTE 500. Должен вывести AJUSTE 400).
Запрос, указанный в ответе, возвращает счета-фактуры 78 и 79. В счете-фактуре 79 указано ESTORNO 100 и AJUSTE 551,20, что верно. В счете-фактуре 78 указано ESTORNO 100 и AJUSTE 200, что тоже верно.
В счете-фактуре 55 указано значение AJUSTE 2000, и он не отображается в результатах.
Надеюсь, все это имеет смысл.
--- второе редактирование -----
Если sum() AJUSTE и ESTORNO в bill_no одинакова, она игнорируется и не включается в результаты.
Если sum() AJUSTE или ESTORNO в инвойсе_no отличается, отобразите оба результата как положительное число.
Payment_id — это первичный ключ. Приношу извинения, поскольку в скрипте mysql его нет.
Ожидаемый результат от скрипта MySQL:
спасибо за информацию Бармар. Можете ли вы показать мне пример, как это будет выглядеть?
Объедините свои подзапросы и покажите только строки с разными суммами по одному и тому же счету.
SELECT e.*
FROM (
select sum(pay_amount) as pay_amount, pay_type, invoice_no
from payments
where pay_type = 'ESTORNO' and pay_date like '%-%-2024' and active = '1'
group by invoice_no, pay_type
) AS e
JOIN (
select sum(pay_amount) as pay_amount, pay_type, invoice_no
from payments
where pay_type = 'AJUSTE' and pay_date like '%-%-2024' and active = '1'
group by invoice_no, pay_type
) AS a ON a.invoice_no = e.invoice_no AND a.pay_amount != e.pay_amount
UNION ALL
SELECT a.*
FROM (
select sum(pay_amount) as pay_amount, pay_type, invoice_no
from payments
where pay_type = 'ESTORNO' and pay_date like '%-%-2024' and active = '1'
group by invoice_no, pay_type
) AS e
JOIN (
select sum(pay_amount) as pay_amount, pay_type, invoice_no
from payments
where pay_type = 'AJUSTE' and pay_date like '%-%-2024' and active = '1'
group by invoice_no, pay_type
) AS a ON a.invoice_no = e.invoice_no AND a.pay_amount != e.pay_amount
Чтобы избежать ошибок ONLY_FULL_GROUP_BY
, необходимо удалить столбцы pay_date
, active
и invoice_date
из списка SELECT
, поскольку они могут быть неуникальны внутри групп.
Я ценю пример Бармара, но я использую MySQL 5.7. Можно ли это сделать в 5.7?
Замените FROM e JOIN a
на FROM (subquery) AS e JOIN (subquery) AS a
, заменив subquery
определениями каждого CTE.
Я ценю ваше время и усилия, но запрос не дал того, что я ищу. По сути, необходимо суммировать все AJUTES и все ESTORNO из каждого счета. Если сумма AJUSTE равна сумме ESTORNO по счету, ее следует игнорировать и в результате не возвращать.
Я думаю, вот что это делает. Он вычисляет отдельные суммы для AJUTES и ESTORNO в каждом подзапросе, а затем сравнивает суммы.
Можете ли вы добавить к вопросу примеры входных данных и ожидаемых результатов? Введите его в виде текста, чтобы его можно было скопировать и вставить для тестирования.
Привет, Бармар. Спасибо за внимание к этому вопросу. Я отредактировал вопрос, так как текст был слишком длинным, чтобы его можно было разместить здесь. Заранее спасибо!
Вам нужно отменить отдельные платежи и корректировки с одинаковыми суммами или только с общими суммами? Пожалуйста, отредактируйте вопрос, чтобы добавить ожидаемые результаты. Кроме того, вам необходимо сделать payment_id
первичным ключом таблицы на mycompiler.io, иначе он получит ошибку от GROUP BY payment_id
.
Привет, Бамар, я снова отредактировал вопрос. Моя рабочий пример не пометила pay_id как первичный ключ. В базе данных это первичный_ключ. извините за это.
Пожалуйста, не размещайте изображения, размещайте текст.
На самом деле, проблема с группировкой все еще существует. Мы группируем по invoice_no
, а не по первичному ключу. В списке SELECT
не может быть других неагрегированных столбцов, поскольку они могут иметь разные значения в разных строках группы.
Приятно знать. На данный момент я не могу изменить структуру базы данных, поэтому мне нужно придумать альтернативу отчету. Я еще раз ценю все ваши усилия. Спасибо
Измените его на просто SELECT invoice_no, pay_type, SUM(pay_amount) AS pay_amount FROM ... GROUP BY invoice_no, pay_type
. Избавьтесь от всех столбцов, поскольку они не будут уникальными.
Но в идеале вам следует нормализовать свои таблицы. Должна быть еще одна таблица счетов и invoice_no
должен быть ФК.
Мне нужно было вернуть YEAR(pay_date)
исходное LIKE
состояние. Я не осознавал, что это VARCHAR
, я предполагал, что это DATE
.
Я сделал скрипку, показывающую результаты.
Давайте продолжим обсуждение в чате.
Посмотреть другой пример
Состояние When the sum of all refunds and adjustments within the same invoice exists and adds up to zero, we skip over that particular invoice.
Итак, первый шаг — расчет суммы для типа оплаты в («AJUSTE», «ESTORNO») для каждого номера счета-фактуры.
Берем счета, общая сумма которых не <>0.
Подзапрос.
select invoice_no
,sum(pay_amount) sum_AE
from payments p
where pay_type in('AJUSTE','ESTORNO') and pay_date like '%-%-2024'
and active = '1'
group by invoice_no
having abs(sum(pay_amount))>0.001
Полный запрос.
Внутреннее объединение предыдущего вывода с таблицей платежей
select p.invoice_no,abs(pay_amount) pay_amount,pay_type
from payments p
inner join(
select invoice_no
,sum(pay_amount) sum_AE
from payments p
where pay_type in('AJUSTE','ESTORNO') and pay_date like '%-%-2024'
and active = '1'
group by invoice_no
having abs(sum(pay_amount))>0.001
)c on p.invoice_no=c.invoice_no
where pay_type in('AJUSTE','ESTORNO')
order by p.invoice_no ;
Вау... ты сделал это. Спасибо!
Обратите внимание, что в предложении
WHERE
pay_amount
относится к значениям в таблице, а неSUM(pay_amount) AS pay_amount
. Чтобы отфильтровать агрегированное значение, вам необходимо поставить условиеHAVING
.