Как выбрать значения из двух таблиц, которые не содержатся в таблице map?
-
20-08-2019 - |
Вопрос
Допустим, у меня есть следующие таблицы:
- Клиенты
- Продукты
- Потребительские продукты
Есть ли способ, которым я могу сделать выбор из таблиц Customers и Products, где значений НЕТ в таблице map?В принципе, мне нужен согласованный список Клиентов и Продуктов, которыми они НЕ владеют.
Еще один поворот:Мне нужно связать одного клиента с каждым продуктом.Таким образом, если у 5 клиентов нет продукта A, только у первого клиента в запросе должен быть Продукт A.Таким образом, результаты будут выглядеть примерно так:
(Предположим, что все клиенты владеют продуктом B, И более одного клиента владеют продуктами A, C и D)
- Клиент 1, Продукт А
- Клиент 2, Продукт C
- Клиент 3, Продукт D
Финальный поворот:Мне нужно выполнить этот запрос как часть инструкции UPDATE в SQL Sever.Итак, мне нужно взять значение из первой строки:
Клиент 1, Продукт А
и обновите запись клиента до чего-то вроде
UPDATE Customers
SET Customers.UnownedProduct = ProductA
WHERE Customers.CustomerID = Customer1ID
Но было бы неплохо, если бы я мог выполнить весь этот процесс в одной инструкции SQL.Итак, я запускаю запрос один раз, и он обновляет 1 клиента продуктом, которым он не владеет.Надеюсь, это не слишком сбивает вас с толку!Заранее спасибо!
Решение
WITH q AS
(
SELECT c.*, p.id AS Unowned,
ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY c.id) AS rn
FROM Customers c
CROSS JOIN
Products p
LEFT JOIN
CustomerProducts cp
ON cp.customer = c.id
AND cp.product = p.id
WHERE cp.customer IS NULL
)
UPDATE q
SET UnownedProduct = Unowned
WHERE rn = 1
UPDATE
заявление обновит Первый клиент, у которого нет определенного продукта.
Если вы хотите выбрать список, вам понадобится:
SELECT *
FROM (
SELECT c.*, p.id AS Unowned,
ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY c.id) AS rn
FROM Customers c
CROSS JOIN
Products p
LEFT JOIN
CustomerProducts cp
ON cp.customer = c.id
AND cp.product = p.id
WHERE cp.customer IS NULL
) cpo
WHERE rn = 1
Другие советы
Если вы обновляете только одного клиента одновременно, вам может потребоваться запомнить, какие продукты были назначены автоматически (в CustomerProducts), или иметь счетчик, как часто продукт назначался автоматически (в Products).
Я попробовал это в oracle (надеюсь, у вас это тоже сработает)
UPDATE customers c
SET unownedProduct =
( SELECT MIN( productid )
FROM products
WHERE productid NOT IN (
SELECT unownedProduct
FROM customers
WHERE unownedProduct IS NOT NULL )
AND productid NOT IN (
SELECT productid
FROM customerProducts cp
WHERE cp.customerId = c.customerid )
)
WHERE customerId = 1
Что делать, если клиент не владеет более чем одним продуктом?и как вы собираетесь поддерживать это поле по мере изменения данных?Я думаю, вам действительно нужно еще немного подумать о вашей структуре данных, поскольку не имеет смысла хранить эту информацию в таблице customer.