2016-06-22 1 views
0

n番目の行のサマリーを返す関数を作成しようとします.nはクエリ結果の順序で定義されます。 これは私が持っているものです:fIngredientfInventoryは、クエリのフィルタのIDであり、fNotefn_inventory_bookテーブルからPKでN行目のMySQLサマリー関数

CREATE DEFINER=`root`@`localhost` FUNCTION `fn_inventory_stock_on_note`(fIngredient int, fInventory int, fNote int) RETURNS float 
    DETERMINISTIC 
BEGIN 
    DECLARE tStock float; 
    DECLARE tNoteRow int; 
    DECLARE tDummy int; 

    DECLARE rStock float; 
    DECLARE rRow int; 

    SET tNoteRow = 0; 
    SET @rRow := 0; 

    SELECT @rRow := @rRow + 1, b.ID 
     INTO tNoteRow, tDummy 
    FROM fn_inventory_book b 
     LEFT JOIN fn_inventory_book_in bi ON b.id = bi.bookid 
     LEFT JOIN fn_inventory_book_out bo ON b.id = bo.bookid 
      LEFT JOIN fn_dict_transactions t ON b.transactionid = t.id 
    WHERE b.inventoryid = fInventory 
     AND (bi.ingredientid = fIngredient OR bo.ingredientid = fIngredient) 
    HAVING b.ID = fNote 
    ORDER BY b.date ASC, t.direction ASC; 

    SET @rRow := 0; 
    SET @rStock := 0; 

    SELECT rStock INTO tStock 
    FROM (SELECT @rRow := @rRow + 1 as rRow, @rStock := @rStock + ifnull(if(bi.id is not null, bi.quantity, bo.quantity), 0) * t.direction as rStock 
      FROM fn_inventory_book b 
       LEFT JOIN fn_inventory_book_in bi ON b.id = bi.bookid 
       LEFT JOIN fn_inventory_book_out bo ON b.id = bo.bookid 
        LEFT JOIN fn_dict_transactions t ON b.transactionid = t.id 
      WHERE b.inventoryid = fInventory 
       AND (bi.ingredientid = fIngredient OR bo.ingredientid = fIngredient) 
      ORDER BY b.date ASC, t.direction ASC) as q 
    WHERE rRow = tNoteRow; 

    RETURN tStock; 

END 

。 最初のselectは必要な行の番号を順番に取得しますが、これは正常に動作します。 私の問題は2番目のクエリにあります。サブクエリでは、同じ行番号と各行の累積数で、最初の選択と同じフィルタと順序でテーブルを作成します。また、メインのクエリでは、最初の選択で取得した行番号でフィルタを適用します。

少なくともこれは何が起こるべきかです。しかし、その代わりに、私は次のような関数を実行するとき: select fn_inventory_stock_on_note(1545, 18, 124167) as stock from dual; それはNULLを返しますが、私は同じパラメータで別々に2番目のクエリを実行すると、私は戻って量を取得します。

しかし、2番目のクエリのサブクエリのみを実行すると、行番号が順番に並んでいないので(1,2,3,6,7,4,5,8,9,10ではなく1 、2,3、...、10)。

私は間違っていますか?どんな助けもありがとう。 私の記述がはっきりしていないかどうか自由に感じてください。

答えて

0

私は自分の問題を解決する方法を見つけましたが、誰かがより良いものを持っていれば、それを分かち合いましょう。私は自分のものが正しいとは思わないからです。

DROP function IF EXISTS `fn_inventory_stock_on_note`; 

DELIMITER $$ 
CREATE DEFINER=`root`@`localhost` FUNCTION `fn_inventory_stock_on_note`(fIngredient int, fInventory int, fNote int, fItem int) RETURNS float 
    DETERMINISTIC 
BEGIN 
    DECLARE tStock float; 
    DECLARE tNoteRow int; 

    DECLARE rStock float; 
    DECLARE rRow int; 

    SET @rRow := 0; 

    DROP TEMPORARY TABLE IF EXISTS stock_temp; 
    CREATE TEMPORARY TABLE stock_temp (num int, BookID int, ItemID int, qty float); 
    INSERT INTO stock_temp (SELECT @rRow := @rRow + 1 as num, q.* 
           FROM (SELECT b.id as BookID, if(bi.id is not null, bi.id, bo.id) as ItemID, 
              ifnull(if(bi.id is not null, bi.quantity, bo.quantity), 0) * t.direction as qty 
             FROM fn_inventory_book b 
              LEFT JOIN fn_inventory_book_in bi ON b.id = bi.bookid 
              LEFT JOIN fn_inventory_book_out bo ON b.id = bo.bookid 
               LEFT JOIN fn_dict_transactions t ON b.transactionid = t.id 
             WHERE b.inventoryid = fInventory 
              AND (bi.ingredientid = fIngredient OR bo.ingredientid = fIngredient) 
             ORDER BY b.date ASC, t.direction ASC) as q); 


    SELECT num INTO tNoteRow 
    FROM stock_temp st 
    WHERE st.BookID = fNote 
     AND st.ItemID = fItem; 


    SELECT sum(st.qty) INTO tStock 
    FROM stock_temp st 
    WHERE st.num <= tNoteRow; 

    RETURN tStock; 

END$$ 

DELIMITER ; 
関連する問題