マップテーブルに含まれていない2つのテーブルから値を選択する方法
-
20-08-2019 - |
質問
次の表があるとしましょう:
- 顧客
- 製品
- CustomerProducts
値がマップテーブルにない、CustomersテーブルとProductsテーブルから選択を行う方法はありますか?基本的に、所有していない顧客と製品の一致したリストが必要です。
別の工夫:製品ごとに1人の顧客をペアリングする必要があります。したがって、5人の顧客が製品Aを持っていない場合、クエリの最初の顧客のみが製品Aを持つ必要があります。したがって、結果は次のようになります。
(すべての顧客が製品Bを所有し、複数の顧客が製品A、C、およびDを所有していると仮定します)
- 顧客1、製品A
- 顧客2、製品C
- 顧客3、製品D
最後の工夫:このクエリは、SQL SeverのUPDATEステートメントの一部として実行する必要があります。したがって、最初の行から値を取得する必要があります。
顧客1、製品A
顧客レコードを次のようなものに更新します
UPDATE Customers
SET Customers.UnownedProduct = ProductA
WHERE Customers.CustomerID = Customer1ID
しかし、このプロセス全体を1つのSQLステートメントで実行できると便利です。そのため、クエリを1回実行すると、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
ステートメントは、特定の製品を所有していない first 顧客を更新します。
リストを選択するには、次のものが必要です。
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人の顧客のみを更新する場合、どの製品が自動的に割り当てられたかを覚えておく必要がある場合があります(CustomerProductsで)、または製品が自動的に割り当てられた頻度をカウンターで確認します(製品で)
私はオラクルでこれを試しました(あなたにもうまくいくことを願っています)
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
顧客が複数の製品を所有していない場合はどうなりますか?また、データが変更されたときにこのフィールドをどのように維持しますか?顧客テーブルにこの情報を保存するのは理にかなっていないので、データ構造についてさらに考える必要があると思います。