Назад к вопросам
Middle
5
Есть таблицы счетов и их позиций. Найти счета, у которых `invoices.total` **НЕ совпадает** с суммой позиций (hours * rate). ## Таблица `invoices`: | id | total | |----|-------| | 1 | 5000 | | 2 | 8000 | | 3 | 3200 | | 4 | 1500 | ## Таблица `invoice_lines`: | invoice_id | service_name | hours | rate | |------------|--------------|-------|------| | 1 | consulting | 10 | 500 | -- 5000 ✓ | 2 | design | 8 | 800 | -- } | 2 | development | 5 | 500 | -- 8900 ≠ 8000 ✗ | 3 | testing | 4 | 800 | -- 3200 ✓ | 4 | support | 2 | 500 | -- } | 4 | analytics | 3 | 300 | -- 1900 ≠ 1500 ✗ ## Ожидаемый результат: | id | total | actual_sum | |----|-------|------------| | 2 | 8000 | 8900 | | 4 | 1500 | 1900 | SELECT id, total, actual_sum ...
Компании, где спрашивали
Лоция
Ответ от нейросети
sobes.tech AI
Для решения задачи нужно сгруппировать позиции по invoice_id, посчитать сумму hours * rate для каждой группы и сравнить с total из таблицы invoices. Затем выбрать те счета, где суммы не совпадают.
Пример SQL-запроса:
SELECT
i.id,
i.total,
COALESCE(SUM(il.hours * il.rate), 0) AS actual_sum
FROM invoices i
LEFT JOIN invoice_lines il ON i.id = il.invoice_id
GROUP BY i.id, i.total
HAVING i.total <> COALESCE(SUM(il.hours * il.rate), 0);
Объяснение:
LEFT JOINгарантирует, что счета без позиций тоже попадут в выборку (если нужно).SUM(il.hours * il.rate)считает сумму по позициям.COALESCEиспользуется, чтобы заменитьNULLна 0, если позиций нет.HAVINGфильтрует счета, где сумма позиций не равнаtotal.
В результате получим таблицу с id, total и фактической суммой позиций actual_sum для счетов с расхождениями.