Как выбрать значения из двух таблиц, которые не содержатся в таблице map?

StackOverflow https://stackoverflow.com/questions/658691

Вопрос

Допустим, у меня есть следующие таблицы:

  • Клиенты
  • Продукты
  • Потребительские продукты

Есть ли способ, которым я могу сделать выбор из таблиц Customers и Products, где значений НЕТ в таблице map?В принципе, мне нужен согласованный список Клиентов и Продуктов, которыми они НЕ владеют.

Еще один поворот:Мне нужно связать одного клиента с каждым продуктом.Таким образом, если у 5 клиентов нет продукта A, только у первого клиента в запросе должен быть Продукт A.Таким образом, результаты будут выглядеть примерно так:

(Предположим, что все клиенты владеют продуктом B, И более одного клиента владеют продуктами A, C и D)

  1. Клиент 1, Продукт А
  2. Клиент 2, Продукт C
  3. Клиент 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top