3

各部門の在庫品目のステータスを追跡する Oracle 11 データベース テーブルがあります。

ITEM_NUMBER DEPT_NO STATUS
----------- --------- ---------
1 AAA OK
2 AAA OK
3 AAA 行方不明
4 BBB OK
5 BBB OK
6 AAA OK
7 AAA OK

アイテムの範囲ごと、部署ごと、ステータスを表示するビューを作成したいと考えています。範囲内のいずれかの項目が MISSING である場合、ステータスは MISSING である必要があり、そうでない場合は OK である必要があります。

上記の例では、ビューの出力は次のようになります。

START END DEPT_NO STATUS
------ ------ ------- ------------
1 3 AAA 欠落
4 5 BBB OK
6 7 AAA OK

部門にレコードのグループが 1 つしかない場合、これは簡単に実行できますが、同じ部門が異なる範囲に表示される可能性があるため、MIN/MAX で GROUP BY を実行すると、2 つの範囲が合計されるため機能しません。部門 AAA の場合:

dept_no、min(アイテム番号)、max(アイテム番号)、min(ステータス)を選択
在庫から
dept_no でグループ化

START END DEPT_NO STATUS
------ ------ ------- ------------
1 7 AAA 欠落
4 5 BBB OK

これはデータベース ビューを使用して行うことができますか、それとも複雑すぎますか?

4

4 に答える 4

1

別の代替手段 (11g で動作)

WITH qry( item_number, dept_no, status, range_id ) as (
    select item_number, dept_no, status, 1 range_id
    from inventory where item_number = 1
    UNION ALL
    select src.item_number, src.dept_no, src.status,  
         case when src.dept_no <> qry.dept_no
              then qry.range_id + 1 else qry.range_id
         end
    from inventory src
    join qry on src.item_number = qry.item_number + 1
)
SELECT range_id, dept_no, min(item_number), max(item_number), min(status)
from qry
group by range_id, dept_no
order by 1
;

  RANGE_ID DEPT_NO MIN(ITEM_NUMBER) MAX(ITEM_NUMBER) MIN(STATUS)
---------- ------- ---------------- ---------------- -----------
         1 AAA                    1                3 MISSING     
         2 BBB                    4                5 OK          
         3 AAA                    6                7 OK    
于 2013-07-24T23:51:33.720 に答える
1

わかりました、これはうまくいくはずです

ps: end と start は予約語で、使用できませんでした。文字を追加しただけですが、これでも明らかな結果です...

SELECT
    i.sstart,
    i.eend,
    i.dept_no,
    MIN(inventory.status) AS status
FROM (
    SELECT 
        DECODE(r, 1, 1, (LAG(max_range_item, 1) OVER(ORDER BY r) + 1)  ) AS sstart,
        max_range_item AS eend,
        dept_no
    FROM (
        SELECT
            rownum AS r,
            item_number AS max_range_item,
            dept_no
        FROM (
                SELECT 
                    item_number, 
                    dept_no, 
                    LEAD(dept_no, 1) OVER (ORDER BY item_number) AS next_dept_no
                FROM
                    inventory
                ORDER BY
                    item_number ASC
              ) i2
        WHERE
            dept_no != next_dept_no
        OR  next_dept_no IS NULL
        ORDER BY
            item_number ASC
        ) inv
    ) i
        JOIN inventory ON inventory.item_number BETWEEN i.sstart AND i.eend
GROUP BY
    i.sstart,
    i.eend,
    i.dept_no
ORDER BY
    i.sstart ASC

フィドル: http://sqlfiddle.com/#!4/944ff3/17

于 2013-07-24T23:35:11.170 に答える