1

次の 2 つの表が与えられた場合、特定のキットを作成するのに適切な量のすべての部品がある倉庫を見つける必要があります。より適切には、各倉庫で作成できるキットの数を見つける必要があります。

在庫テーブル: Warehouse、Part、および QuantityOnHand
キット テーブル: Kit、Part、QuantityForKit

例: Kit1 には、Part1 が 1 つ、Part2 が 2 つ、Part3 が 1 つ必要です。倉庫 A には、Part1 が 20 個、Part2 が 5 個、Part3 が 3 個あります。倉庫 B には、Part1 が 5 つ、Part2 が 10 あり、Part3 はありません。

倉庫 A は、2 つ以上のキットを作成するのに十分な Part2 がないため、Kit1 を 2 つしか作成できません。必要な部品がすべて揃っていないため、倉庫 B は Kit1 を作成できません。

動作する次のデモがありますが、非常に面倒で、ほとんどの場合テーブル/インデックス スキャンを使用します。インベントリ テーブルが大きく、実行速度が遅すぎます。同じことを達成するためのより良い方法を探しています。デモでは無制限のクロス結合がありますが、実際のアプリでは 1 つのキットに限定されています。

CREATE TABLE #warehouse
(
    Warehouse CHAR(1) NOT NULL PRIMARY KEY
)
INSERT INTO #warehouse VALUES ('A')
INSERT INTO #warehouse VALUES ('B')
INSERT INTO #warehouse VALUES ('C')
INSERT INTO #warehouse VALUES ('D')

CREATE TABLE #inventory
(
    Warehouse CHAR(1) NOT NULL ,
    Part INT NOT NULL ,
    OnHand INT NOT NULL ,
    CONSTRAINT pk_inventory PRIMARY KEY CLUSTERED (Part, Warehouse)
)
INSERT INTO #inventory VALUES ('A', 1, 20)
INSERT INTO #inventory VALUES ('A', 2, 5)
INSERT INTO #inventory VALUES ('A', 3, 3)
INSERT INTO #inventory VALUES ('B', 1, 5)
INSERT INTO #inventory VALUES ('B', 2, 10)
INSERT INTO #inventory VALUES ('C', 1, 1)
INSERT INTO #inventory VALUES ('C', 3, 1)
INSERT INTO #inventory VALUES ('D', 1, 1)
INSERT INTO #inventory VALUES ('D', 2, 2)
INSERT INTO #inventory VALUES ('D', 3, 1)

CREATE TABLE #kit
(
    Kit INT NOT NULL ,
    Part INT NOT NULL ,
    Quantity INT NOT NULL ,
    CONSTRAINT pk_kit PRIMARY KEY CLUSTERED (Kit, Part)
)
INSERT INTO #kit VALUES (1, 1, 1)
INSERT INTO #kit VALUES (1, 2, 2)
INSERT INTO #kit VALUES (1, 3, 1)
INSERT INTO #kit VALUES (2, 1, 1)
INSERT INTO #kit VALUES (2, 2, 1)


    -- Here's the statement I need to optimize
SELECT 
    Warehouse, 
    Kit, 
    MIN(Capacity) AS [Capacity]
FROM
    (
    SELECT 
        A.Warehouse, 
        A.Kit, 
        A.Part, 
        ISNULL(B.OnHand, 0) AS [Quantity], 
        ISNULL(B.OnHand, 0) / A.Quantity AS Capacity 
    FROM 
        (
        SELECT * 
        FROM 
            #warehouse
            CROSS JOIN
                            -- (SELECT * FROM
            #kit
                            -- WHERE #kit.Kit = @Kit) K
        ) A
        LEFT OUTER JOIN
        #inventory B
            ON A.Warehouse = B.Warehouse
            AND A.Part = B.Part
    ) C
GROUP BY
    Warehouse, 
    Kit
;

提案をいただければ幸いです。

4

1 に答える 1

1

これを試して:

SELECT warehouse, MIN(capacity) FROM (
  SELECT i.warehouse, i.onhand / k.quantity as capacity
  FROM #kit k
  JOIN #inventory i
    ON k.part = i.part AND k.quantity <= i.onhand
  WHERE k.kit = @kit) c
GROUP BY warehouse
HAVING COUNT(*) = (SELECT COUNT(*) FROM #kit WHERE kit = @kit)

ここでsqlfiddle

于 2012-12-24T19:22:13.077 に答える