простой запрос / SQL

Как вывести клиентов и книги, которые они НЕ заказывали, по таблицам следующего вида (скрин):

введите сюда описание изображения

Таблицы нужно соединять через JOIN'ы


Ответы (1 шт):

Автор решения: Yitzhak Khabinsky

Пожалуйста, попробуйте следующее решение. Это для MS SQL Server, но вы можете изменить его для любой СУБД.

CTE получает все возможные комбинации между клиентами и книгами через CROSS JOIN, затем EXCEPT отфильтровывает уже заказанные книги.

SQL

-- DDL и образец вставки данных, начало
DECLARE @customer TABLE (custID INT PRIMARY KEY, cust_name VARCHAR(20));
INSERT @customer (custID, cust_name) VALUES
(1, 'Anna'),
(2, 'Lena');

DECLARE @book TABLE (bookID INT PRIMARY KEY, book_title VARCHAR(20));
INSERT @book (bookID, book_title) VALUES
(1, 'War and Peace'),
(2, 'Anna Karenina');

DECLARE @customer_book TABLE (custID INT, bookID INT);
INSERT @customer_book (custID, bookID) VALUES
(1, 1);
-- DDL и образец вставки данных, конец

SELECT * FROM @customer;
SELECT * FROM @book;
SELECT * FROM @customer_book;

;WITH rs AS
(
    SELECT c.custID, b.bookID 
    FROM @customer AS c
        CROSS JOIN @book AS b
    EXCEPT
    SELECT custID, bookID FROM @customer_book
)
SELECT c.*, b.book_title
FROM rs
    INNER JOIN @customer AS c ON c.custID = rs.custID
    INNER JOIN @book AS b ON b.bookID = rs.bookID
ORDER BY c.cust_name, b.book_title;

Результат

custID cust_name book_title
1 Anna Anna Karenina
2 Lena Anna Karenina
2 Lena War and Peace
→ Ссылка