2017-06-12 61 views
1

我有一個表類似下面:MAX和SUM查詢從同桌

part | location | qty 
    1 | Seattle | 2 
    2 | New York | 3 
    2 | New York | 2 
    1 | Seattle | 1 
    1 | New York | 1 
    1 | Warehouse | 5 

這意味着部分我有3成部分的人在西雅圖,一個在紐約(忽略此時倉庫)。如果我有一個位置,讓我們在達拉斯說,需要的第1部分股票,我想西雅圖,因爲他們擁有比紐約發送。

SELECT part 
     ,SUM(QTY_AVAILABLE) AS QTY_AVAILABLE 
     ,LOCATION 
FROM table1 
WHERE LOCATION IN ('Warehouse','New York','Seattle','Dallas') 
GROUP BY PN, LOCATION 

以上給出了每個位置的庫存數量。我只想顯示每個零件庫存量最多的上面的位置。

我的問題的第二部分,我怎麼能顯示的位置到部分來自轉移而忽略了倉庫有一部分的事實,除非沒有位置,但該倉內有一部分?如果紐約用完了第二部分,但倉庫擁有它,那麼查詢應該說該部分需要來自倉庫。

在此先感謝您的幫助。

+0

零件是否一次裝運一件(數量爲1)?如果你需要4的數量,倉庫有10個,但是紐約有2個,達拉斯有1個,西雅圖有1個 - 如果所有4個都應該從倉庫發貨,還是應該從紐約,達拉斯和西雅圖運送?你的描述表明它應該來自紐約,達拉斯和西雅圖,但這的確是期望的答案? – mathguy

+0

的主要目的是讓那些不使用產品,運到某處,並使用它的商店。查詢的另一部分加入誰擁有一個項目,但一年沒有使用它。如果位置1只需要4,他們最終會得到4個,但我還是想位置2送1的數量,因爲它只是收集灰塵。 – arcadeil

+0

OK,然後我昨天張貼的解決方案可能是你所需要的。那是我做的假設。 – mathguy

回答

1

像這樣的東西應該工作 - 在一個查詢。注意「測試數據」中的其他示例(我添加了第3部分和第4部分,每部分都有不同的情況)。我沒有過濾,所以唯一的地點是紐約,西雅圖和達拉斯;如果需要,這很容易做到。

with 
    test_data (part, location, qty) as (
     select 1, 'Seattle' , 2 from dual union all 
     select 2, 'New York' , 3 from dual union all 
     select 2, 'New York' , 2 from dual union all 
     select 1, 'Seattle' , 1 from dual union all 
     select 1, 'New York' , 1 from dual union all 
     select 1, 'Warehouse', 5 from dual union all 
     select 3, 'Dallas' , 2 from dual union all 
     select 3, 'Warehouse', 4 from dual union all 
     select 4, 'Warehouse', 3 from dual 
    ) 
-- End of test data (not part of the solution). Query begins BELOW THIS LINE. 
select part, location, sum_qty 
from  (
      select part, location, sum(qty) as sum_qty, 
        row_number() over (partition by part 
             order by case when location != 'Warehouse' 
                 then 0 end, 
               sum(qty) desc 
            ) as rn 
      from  test_data 
      group by part, location 
     ) 
where rn = 1 
order by part 
; 

PART LOCATION  SUM_QTY 
----- --------- ---------- 
    1 Seattle   3 
    2 New York   5 
    3 Dallas    2 
    4 Warehouse   3 
+0

這實際上也是我打算輸出的內容。好,@mathguy。 – SandPiper

+0

它看起來像這樣做,但它現在連接不正確的另一個子查詢,所以我不能100%肯定。看起來我只需要切換一些東西,但它確實是我想要的。萬分感謝! – arcadeil

0

首先使用RANK函數來選擇最上面的一個給定的部分是這樣的:

select part, location from ( 
    select 
     row_number() over (order by sum(qty) desc) rn, 
     part, 
--  sum(qty) as qty_available, 
     location 
    from test 
    where location in ('Warehouse','New York','Seattle','Dallas') 
    group by part, location 
    ) where rn = 1; 
-- group by part, location 

其次使用過濾器與非零股票地點和模擬有部分1位置的選擇,一旦新紐約跑出股票。

select part, location from ( 
    select 
     row_number() over (partition by part order by sum(qty) desc) rn, 
     part, 
     sum(qty) as qty_available, 
     location 
    from test 
    where location in ('Warehouse', 
    -- 'New York', -- New York ran out of the parts 
    'Seattle','Dallas') 
    group by part, location 
    ) where rn = 1 
    and part = 1 
    and qty_available > 1; 

我希望這會有好處。

0

我認爲有以下也適用:

SELECT i.* 
FROM inventory i 
INNER JOIN (SELECT i2.part_no, MAX(i2.stock) AS STOCK 
      FROM inventory i2 
      WHERE i2.location <> 'Warehouse' 
      GROUP BY i2.part_no) sub ON i.part_no = sub.part_no AND i.stock = sub.stock 
WHERE i.location <> 'Warehouse' 
UNION ALL 
SELECT * 
FROM inventory i 
WHERE i.location = 'Warehouse' 
AND NOT EXISTS (SELECT 'x' 
       FROM inventory i2 
       WHERE i2.part_no = i.part_no 
       AND i2.location <> 'Warehouse'); 

對於你的問題的第一部分,你可以用的上半部分,並把該東東刪除有關位置<>「倉庫」