如何从两个表中选择未包含在映射表中的值?

时间:2009-03-18 15:12:24

标签: sql sql-server stored-procedures subquery nested-queries

假设我有以下表格:

  • 客户
  • 产品
  • CustomerProducts

有没有办法可以从Customers和Products表中进行选择,其中值不在map表中?基本上我需要一份他们不拥有的客户和产品的匹配列表。

另一个转折:我需要为每个产品配对一个客户。因此,如果5个客户没有产品A,则只有查询中的第一个客户应该有产品A.所以结果看起来像这样:

(假设所有客户都拥有产品B,并且不止一个客户拥有产品A,C和D)

  1. 客户1,产品A
  2. 客户2,产品C
  3. 客户3,产品D
  4. 最后的转折:我需要在SQL Sever中将此查询作为UPDATE语句的一部分运行。所以我需要从第一行获取值:

    客户1,产品A

    并将客户记录更新为

    UPDATE Customers
    SET Customers.UnownedProduct = ProductA
    WHERE Customers.CustomerID = Customer1ID
    

    但如果我能在一个SQL语句中完成整个过程,那就太好了。所以我运行一次查询,它用一个他们不拥有的产品更新1个客户。 希望对你来说不会太混乱!提前谢谢!

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:0)

如果您一次只更新一个客户,您可能需要记住哪些产品已自动分配(在CustomerProducts中)或者有一个计数器自动分配产品的频率(在产品中)

答案 2 :(得分:0)

我在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

答案 3 :(得分:0)

如果客户不拥有多个产品,该怎么办?当数据发生变化时,您将如何维护此字段?我认为您真的需要更多地考虑您的数据结构,因为将这些信息存储在客户表中是没有意义的。