SQL - создание внутреннего соединения для двух столбцов внутри одной таблицы - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь решить практическую проблему из моей книги.Проблема выглядит следующим образом:

Найдите всех поставщиков, у которых есть счета, которые еще не оплачены.(Подсказка: invoice_total будет отличаться от payment_total).

Перепишите вышеуказанный запрос в общей сложности 3 способами: используя equijoins, используя INNER JOIN и NATURAL JOIN.

Я выполнилПервый шаг:

SELECT DISTINCT VENDOR_ID
FROM INVOICES
WHERE Invoice_Total != payment_total;

Однако, когда я пытаюсь выполнить внутренние объединения, я продолжаю получать ошибки.И Invoice_Total, и Payment_Total являются столбцами внутри одной и той же таблицы «СЧЕТЫ».

Как я могу показать несоответствия, извлекая идентификаторы поставщиков?

Это изображение базы данных практики, с которой я работаю.

1 Ответ

0 голосов
/ 21 сентября 2018

Кажется глупым внутреннее объединение таблицы с самим собой для решения этой конкретной проблемы (есть много веских причин для самостоятельного объединения, но это не одна из них), но я полагаю, с точки зрения "проблемы практики"это разумно

Я думаю, что здесь было бы лучше предварительно агрегировать invoices перед объединением, чтобы сократить время обработки (если не существует индекса, помогающего объединению):

SELECT t1.vendor_id
FROM (SELECT vendor_id, sum(invoice_total) sum_invoice_total FROM INVOICES GROUP BY vendor_id) t1
    INNER JOIN (SELECT vendor_id, sum(payment_total) sum_payment_total FROM INVOICES GROUP BY vendor_id) t2
        ON t1.vendor_id = t2.vendor_id
WHERE
    t1.sum_invoice_total != t2.sum_payment_total

Существует вероятность того, что это может выйти из строя, хотя если поставщик может переплатить за счет.Рассмотрим:

+------------+-----------+---------------+---------------+
| invoice_id | vendor_id | invoice_total | payment_total |
+------------+-----------+---------------+---------------+
|          1 | a         |            10 |            20 |
|          2 | a         |            10 |             0 |
+------------+-----------+---------------+---------------+

Без предварительной агрегации (опять же, это не имеет смысла, но это будет работать):

SELECT DISTINCT t1.vendor_id
FROM invoices t1
    INNER JOIN invoices t2
        ON t1.invoice_id = t2.invoice_id
WHERE
    t1.invoice_total != t2.payment_total

Это почти идентично вашему исходному запросу, но добавляет влишнее внутреннее соединение.Я просто угадаю ваш первичный ключ как invoice_id здесь.Редактировать при необходимости.

...