2016-08-02 79 views
3

我有一個查詢返回數據庫中所有可用庫存。 I 需要製作一個存儲過程來獲取用戶輸入的特定項目的itemCode,batchNo,數量和價格。存貨清單上的先入先出

---------------------------------------------- 
| id | itemCode | batchNo | availQty | price | 
---------------------------------------------- 
| 1 | item_1 | 07292016| 5  | 5.50 | 
| 2 | item_1 | 07312016| 10  | 5.50 | 
| 3 | item_1 | 08012016| 2  | 6.00 | 

我的問題是,如果用戶輸入要購買6數量,我怎麼能拿到第2行的結果獲得6個總數量是多少?

結果必然是:

07292016 --- 5 
07312016 --- 1 
+0

郵政查詢更多的澄清 –

+0

標籤的問題與您的SQL服務器版本。如果它支持SUM OVER()解決方案很簡單。 – Serg

+0

@jarlh,謝謝你的澄清。 – princevezt

回答

1

我懷疑這是有效的,查詢是horid,但下面會給你想要的東西:

-- Create Test Data 
create table #Items 
(
    id int not null primary key, 
    itemCode varchar(30) not null, 
    batchNumber varchar(30) not null, 
    availQty int not null, 
    price smallmoney not null 
); 

insert into #Items 
values 
    (1, 'item_1', '07292016', 5, 5.50), 
    (2, 'item_1', '07312016', 10, 5.50), 
    (3, 'item_1', '08012016', 2, 6.00) 

select 
    * 
from 
    #Items 
; 

-- Set up required parameters 
declare 
    @requiredItemCode varchar(30) = 'item_1', 
    @requiredQty int = 6 

-- The query to get the required result 
select 
    i.*, 
    case 
     when 
      @requiredQty - 
      isnull(
       (
        select 
         sum(availQty) 
        from 
         #Items i2 
        where 
         i2.itemCode = i.itemCode 
         and i2.id < i.Id 
       ), 
       0) < i.availQty 
     then 
      @requiredQty - 
      isnull(
       (
        select 
         sum(availQty) 
        from 
         #Items i2 
        where 
         i2.itemCode = i.itemCode 
         and i2.id < i.Id 
       ), 
       0) 
     else 
      i.availQty 
    end as qtyToTake 
from 
    #Items i 
where 
    i.ItemCode = @requiredItemCode 
    and 
    case 
     when 
      @requiredQty - 
      isnull(
       (
        select 
         sum(availQty) 
        from 
         #Items i2 
        where 
         i2.itemCode = i.itemCode 
         and i2.id < i.Id 
       ), 
       0) < i.availQty 
     then 
      @requiredQty - 
      isnull(
       (
        select 
         sum(availQty) 
        from 
         #Items i2 
        where 
         i2.itemCode = i.itemCode 
         and i2.id < i.Id 
       ), 
       0) 
     else 
      i.availQty 
    end > 0 

-- Clean up test data 
drop table #Items 

輸出:

id   itemCode batchNumber availQty price 
----------- -------- ----------- ----------- --------------------- 
1   item_1 07292016 5   5.50 
2   item_1 07312016 10   5.50 
3   item_1 08012016 2   6.00 

(3 row(s) affected) 

id   itemCode batchNumber availQty price     qtyToTake 
----------- -------- ----------- ----------- --------------------- ----------- 
1   item_1 07292016 5   5.50     5 
2   item_1 07312016 10   5.50     1 

(2 row(s) affected) 
+0

感謝您的幫助先生。 @martin – princevezt

+0

先生,你可以點亮我在線 「和i2.id princevezt

+0

「和i2.id i.Id,你會得到帶有ID 2和3的行而不是1和2行。 –

0

我沒有測試過,但你仍然可以做在此之上的變化,如果你有任何問題。希望你想要這個

CREATE OR ALTER PROCEDURE dbo.getStock @item_Code nvarchar(30), @quantity int 
    AS 
    //Declare variables 
    DECLARE @id INT 
    DECLARE @itemCode nvarchar(30) 
    DECLARE @batchNo nvarchar(30) 
    DECLARE @qty INT 
    DECLARE @cumulativeQty INT 
    DECLARE @price DECIMAL(18,2) 

    //Declare cursor 
    DECLARE @getStock CURSOR 
    SET @getStock = CURSOR FOR 
    SELECT Id, ItemCode, batchNo, availQty, price 
    FROM your_table 
    WHERE ItemCode = @item_Code 
    ORDER BY batchNo ASC 

    //Create temp table to store all of the intermediate stock records into it 

    //If always make sure if its already exist just drop and recreate 



IF OBJECT_ID('tempdb..#TmpStock') IS NOT NULL 
    BEGIN 
     DROP TABLE #TmpStock 
    END 
    ELSE 
    BEGIN 
     CREATE TABLE #TmpStock(Id INT, ItemCode nvarchar(30), BatchNo nvarchar(30), Quatnity INT, Price Decimal(18,2)) 
    END 


    //Open the cursor 
    OPEN @getStudents 

    //Read the next row record into the cursor 
    FETCH NEXT 
    FROM @getStock INTO @id, @itmCode, @batchNo, @qty, @price 


    SET @cumulativeQty = 0 

    //Loop through one row by another which is selected above and stored in cursor 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 

    //If the cumulative quantity is less than user's input quantity 
    //then keep inserting into the temp table and deduct the inserted qty 
    SET @cumulativeQty = @cumulativeQty + @qty 

    IF(@quantity <= @cumulativeQty) 
     INSERT INTO #TmpStock VALUES(@id, @itmCode, @batchNo, @quantity, @price); 
    ELSE 
     INSERT INTO #TmpStock VALUES(@id, @itmCode, @batchNo, @qty, @price); 
    @cumulativeQty= @quantity - @qty 
    END 

    FETCH NEXT 
    FROM @getStock INTO @id, @itmCode, @batchNo, @qty, @price 
    END 


    //Closing the cursor 
    CLOSE @getStock 
    DEALLOCATE @getStock 

//Now select your data from temp table 
SELECT * FROM #TmpStock 
1

試試這個

DECLARE @Tbl TABLE (id INT, itemCode NVARCHAR(50), batchNo NVARCHAR(50), availQty INT, price DECIMAL(5,2)) 

INSERT INTO @Tbl VALUES   
(1, 'item_1' , '07292016', 5  , 5.50), 
(2 , 'item_1', '07312016' ,10, 5.50), 
(3 , 'item_1', '08012016' ,2 , 6.00) 


DECLARE @Quantity INT = 6 

SELECT * 
FROM 
    @Tbl 
WHERE 
    id <= (
      SELECT TOP 1 
        A.id 
      FROM 
      (
       SELECT 
        id , 
        itemCode , 
        batchNo , 
        availQty , 
        price, 
        (SELECT SUM(availQty) FROM @Tbl IT WHERE IT.id <= T.id) AS TotalAmount 
       FROM 
        @Tbl T 
      ) A 
      WHERE 
       A.TotalAmount >= @Quantity 
      ORDER BY A.id 
     ) 

輸出:

id itemCode batchNo  availQty price 
1 item_1  07292016 5   5.50 
2 item_1  07312016 10   5.50 

修訂

SELECT 
    R.id , 
    R.itemCode , 
    R.batchNo , 
    R.availQty , 
    R.price , 
    CASE WHEN R.MaxId = id THEN R.availQty - (TotalQuantity - @Quantity) 
     ELSE R.availQty END OutQuantity 
FROM 
(
    SELECT 
     id , 
     itemCode , 
     batchNo , 
     availQty , 
     price, 
     MAX(id) OVER (ORDER BY (SELECT NULL)) MaxId, 
     SUM(availQty) OVER (ORDER BY (SELECT NULL)) TotalQuantity 
    FROM 
     @Tbl 
    WHERE 
     id <= (
       SELECT TOP 1 
         A.id 
       FROM 
       (
        SELECT 
         id , 
         itemCode , 
         batchNo , 
         availQty , 
         price, 
         (SELECT SUM(availQty) FROM @Tbl IT WHERE IT.id <= T.id) AS TotalAmount 
        FROM 
         @Tbl T 
       ) A 
       WHERE 
        A.TotalAmount >= @Quantity 
       ORDER BY A.id 
      ) 
) R 
WHERE 
    @Quantity > 0 

輸出

id itemCode batchNo  availQty price OutQuantity 
1 item_1  07292016 5   5.50 5 
2 item_1  07312016 10   5.50 1 
+0

感謝您的幫助。但是你能否給出一個想法,在第2行中如何獲得1個數量?謝謝 – princevezt

+0

@princevezt答案已更新。 – NEER

+0

作爲參考,SUM(...)OVER(ORDER BY ...)在2012年以前版本的SQL Server中不受支持。 –