#sql #postgresql #postgresql-12
Вопрос:
По мере того как я изучаю внешнее соединение слева, я пришел к выводу
Левое внешнее соединение B = все в A и общее в B, отражающее соответствующее значение в таблице результатов, другие значения A, которые не имеют общих значений с таблицей B, имеют нулевое значение в стороне B.
Таким образом, если A имеет 15 значений, B имеет 29 значений(5 общих), то результатом следующего запроса будет 15. Или, если A имеет 15 значений, B имеет 10 значений(5 общих), результат все равно будет 15.
select count(*) from A left outer join B on A.name=B.name;
моя проблема:
У меня есть база данных dvdrental. Таблица клиентов, Таблица платежей. У них 599 14596 строк соответственно.
Когда я запускаю запрос: (я ожидал 14 596 и получил 14 596)
select count(*) from payment left outer join customer on payment.customer_id=customer.customer_id;
но когда я поменялся столами, то есть;( Я ожидал 599, но получил 14 596)
select count(*) from customer left outer join payment on payment.cusotmer_id=customer.customer_id;
почему? Я не могу понять. Справка
Комментарии:
1. Может быть, у ваших клиентов несколько платежей? Возможно, вам придется объединить их, если вам нужна только одна платежная информация для каждого клиента.
2. Когда каждая строка в каждой таблице совпадает с другой таблицей, обычное внешнее соединение между таблицами между ожидаемыми ключами всегда будет возвращать (по крайней мере, но может быть и больше) количество строк в таблице привязки, поскольку нет случаев несоответствия. Это так же, как результат внутреннего соединения.
3. Предоставьте полный тестовый случай с
CREATE TABLE
инструкциями иINSERT
утверждениями, с минимальным количеством строк, необходимых для создания поведения, которое вы не понимаете.4. Когда все ключи совпадают в ваших таблицах, вы говорите A x B. И A x B — это то же самое, что B x A…..
5. Это означает, что у вас нет платежей незарегистрированных клиентов.
Ответ №1:
Это похоже на внутреннее соединение, так как нет несоответствий:
Примечание: Не стесняйтесь изменять имя val
столбца customer_id
на следующее. Результат будет тот же самый.
WITH cte1 (id, val) AS (SELECT 1, 100 UNION SELECT 2, 100) , cte2 (id, val) AS (SELECT 10, 100) SELECT COUNT(*) FROM cte1 LEFT JOIN cte2 ON cte1.val = cte2.val ;
и
WITH cte1 (id, val) AS (SELECT 1, 100 UNION SELECT 2, 100) , cte2 (id, val) AS (SELECT 10, 100) SELECT COUNT(*) FROM cte2 LEFT JOIN cte1 ON cte1.val = cte2.val ;
произведет такое же количество (2).
Ответ №2:
Я думаю, что реальная проблема заключается в том, какой из них вы выберете в качестве таблицы привязки. потому что он помещает другой поверх него и выполняет сложение. Здесь нет одного платежа клиента, например, когда мы смотрим на первую таблицу платежей, когда мы ставим счетчик на первую таблицу платежей, это приведет к 5 клиентам, потому что результат основан на таблице платежей. В другой возможности, когда таблица клиентов основана, она приносит шесть результатов. Как можно понять, какой из них вы выберете, зависит от базовой таблицы.
--customer (count 6) , payment (5) WITH payment(customer_id,paid) AS (SELECT 1,100 UNION SELECT 2,200 UNION SELECT 3,300 UNION SELECT 4,400 UNION SELECT 5,500 ) ,customer(customer_id) AS (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) SELECT COUNT(*) FROM payment py LEFT OUTER JOIN customer ct ON py.customer_id=ct.customer_id; WITH payment(customer_id,paid) AS (SELECT 1,100 UNION SELECT 2,200 UNION SELECT 3,300 UNION SELECT 4,400 UNION SELECT 5,500 ) ,customer(customer_id) AS (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) SELECT COUNT(*) FROM customer ct LEFT OUTER JOIN payment py ON py.customer_id=ct.customer_id;