2017-01-06 14 views
1

私は自分のSQLで材料の使用状況を追跡しようとしています。部品が元の順序で使用されたときにデータベースにリンクする方法はありません。部品は、注文が到着した後に単にビンに入り、部品の使用は基本的に、トランザクション時に使用される部品の数のレコードを作成するだけです。私は可能な限り最善の方法で、データを合計して注文番号に順番に割り当てることによって、注文番号への使用をリンクしようとしています。 私のサブクエリは、これまで私を得てくれました。各注文番号は日付で受信されます。私はUSEDATEに基づいて、注文の受領書と同等かそれ以上になる必要がある使用表レコードに参加します。このことにより、生成されたデータは以下のようなある:Oracle SQLデータを順番に結合する

| ORDERNUM | PARTNUM |  RECEIVEDATE  | ORDERQTY | USEQTY |  USEDATE   | 
|----------|----------|-------------------------|-----------|---------|------------------------| 
|  4412 | E1125 | 10/26/2016 1:32:25 PM |   1 |  1 | 11/18/2016 1:40:55 PM | 
|  4412 | E1125 | 10/26/2016 1:32:25 PM |   1 |  3 | 12/26/2016 2:19:32 PM | 
|  4412 | E1125 | 10/26/2016 1:32:25 PM |   1 |  1 | 1/3/2017 8:31:21 AM | 
|  4111 | E1125 | 10/28/2016 2:54:13 PM |   1 |  1 | 11/18/2016 1:40:55 PM | 
|  4111 | E1125 | 10/28/2016 2:54:13 PM |   1 |  3 | 12/26/2016 2:19:32 PM | 
|  4111 | E1125 | 10/28/2016 2:54:13 PM |   1 |  1 | 1/3/2017 8:31:21 AM | 
|  0393 | E1125 | 12/22/2016 11:52:04 AM |   3 |  3 | 12/26/2016 2:19:32 PM | 
|  0393 | E1125 | 12/22/2016 11:52:04 AM |   3 |  1 | 1/3/2017 8:31:21 AM | 
|  7812 | E1125 | 12/27/2016 10:56:01 AM |   1 |  1 | 1/3/2017 8:31:21 AM | 
|  1191 | E1125 | 1/5/2017 1:12:01 PM |   2 |  0 | null     | 

上記のセクションのためのクエリのようなになります。

SELECT 
B.*, 
NVL(B2.QTY, ‘0’) USEQTY 
B2.USEDATE USEDATE 
FROM <<Sub Query B>> 
LEFT JOIN USETABLE B2 ON B.PARTNUM = B2.PARTNUM AND B2.USEDATE >= B.RECEIVEDATE 

ここに私の究極の目標は、彼らが十分なORDERQTYのを満たしている順次までUSEQTYレコードに参加することです。また、USEQTY列のQTYが実際にそのレコードに適用されたことを表すORDERUSE列を追加する必要があります。私は、クエリは上記のような情報を引き出すために得ることができる場合、私は、ことができるようになります

| ORDERNUM | PARTNUM |  RECEIVEDATE  | ORDERQTY | USEQTY |   USEDATE  | ORDERUSE | 
|----------|----------|-------------------------|-----------|---------|------------------------|-----------| 
|  4412 | E1125 | 10/26/2016 1:32:25 PM |   1 |  1 | 11/18/2016 1:40:55 PM |   1 | 
|  4111 | E1125 | 10/28/2016 2:54:13 PM |   1 |  3 | 12/26/2016 2:19:32 PM |   1 | 
|  0393 | E1125 | 12/22/2016 11:52:04 AM |   3 |  2 | 12/26/2016 2:19:32 PM |   2 | 
|  0393 | E1125 | 12/22/2016 11:52:04 AM |   3 |  1 | 1/3/2017 8:31:21 AM |   1 | 
|  7812 | E1125 | 12/27/2016 10:56:01 AM |   1 |  0 | null     |   0 | 
|  1191 | E1125 | 1/5/2017 1:12:01 PM |   2 |  0 | null     |   0 | 

:私は上の表に基づいて起こるために必要なものの一例であるどのように単語この任意のより良いので、ここでは本当にわかりませんレコードをグループ化してORDERUSE列を合計すると、どのオーダーが使用されていて、どれが完全に使用されていないのかを知る必要があります。上記の例では、各ORDERNUMのORDERUSE列を合計すると、4412、4111、0393の注文はすべて完全に使用されます。注文7812,1191は、完全に使用されていないことを示します。

答えて

1

これを正しく読んでいる場合は、使用された部品の数を確認する必要があります。あなたの例では、あなたが5つの使用法を持っているように見え、5つの注文が合計8つの部分に来て、次の注文が使用されているようです。

  • 4412から
  • 4111を使用したもの - - 一部分一部分 - 一つ
  • 7812を使用する - 一つの部分 -
  • 0393を使用する一から三個の パーツ - 二人は

を使用少しハッキングした後、私は次のSQLを思いついた。これがサンプルデータの外で動作するかどうかは、私がテストに使った唯一のものであり、私はエキスパートではありません。

WITH data 
AS (SELECT * 
    FROM (SELECT * 
      FROM sub_b1 
        join (SELECT ROWNUM rn 
          FROM dual 
          CONNECT BY LEVEL < 15) a 
         ON a.rn <= sub_b1.orderqty 
      ORDER BY receivedate) 
    WHERE ROWNUM <= (SELECT SUM(useqty) 
         FROM sub_b2)) 
SELECT sub_b1.ordernum, 
    partnum, 
    receivedate, 
    orderqty, 
    usage 
FROM sub_b1 
    join (SELECT ordernum, 
       Max(rn) AS usage 
     FROM data 
     GROUP BY ordernum) b 
    ON sub_b1.ordernum = b.ordernum 
0

"FIFO"在庫管理を探しています。

適切なデータモデルには、「受信済み」部分と「配信済み」または「使用済み」の2つの表が必要です。各表には、注文番号、その注文の部品番号と数量(受信済みまたは使用済み)、タイムスタンプまたは日付時刻が表示されます。私は以下のクエリでCTEの両方をモデル化しますが、あなたのビジネスでは2つの別々のテーブルにする必要があります。また、トリガーなどは、在庫が入手可能になるまでパーツを使用できないという制約を適用する必要があります(つまり、各パーツID、開始時点以降に使用された総量は、すべての数量を超えてはなりません)開始時点から同じ時点で受け取った)。私は、2つの入力テーブルが実際にこの条件を満たすと仮定し、私はそれをソリューションでチェックしません。

出力には、タイムスタンプごとに、使用された量のタイムラインが表示され、各part_idの「受信済み」および「配信済み(使用済み)」量が一致します。サンプルデータでは、1つのpart_idを示していますが、クエリは複数のpart_idと、数量の異なる複数のパート(パートID)を含むオーダー(受信用と配信用または使用済みの両方)で動作します。

with 
    received (order_id, part_id, ts, qty) as (
     select '0030', '11A4', timestamp '2015-03-18 15:00:33', 20 from dual union all 
     select '0032', '11A4', timestamp '2015-03-22 15:00:33', 13 from dual union all 
     select '0034', '11A4', timestamp '2015-03-24 10:00:33', 18 from dual union all 
     select '0036', '11A4', timestamp '2015-04-01 15:00:33', 25 from dual 
    ), 
    delivered (order_id, part_id, ts, qty) as (
     select '1200', '11A4', timestamp '2015-03-18 16:30:00', 14 from dual union all 
     select '1210', '11A4', timestamp '2015-03-23 10:30:00', 8 from dual union all 
     select '1220', '11A4', timestamp '2015-03-23 11:30:00', 7 from dual union all 
     select '1230', '11A4', timestamp '2015-03-23 11:30:00', 4 from dual union all 
     select '1240', '11A4', timestamp '2015-03-26 15:00:33', 1 from dual union all 
     select '1250', '11A4', timestamp '2015-03-26 16:45:11', 3 from dual union all 
     select '1260', '11A4', timestamp '2015-03-27 10:00:33', 2 from dual union all 
     select '1270', '11A4', timestamp '2015-04-03 15:00:33', 16 from dual 
    ), 

(試験データの終わり; SQLクエリは、以下の始まり - ちょうど上部にある単語WITHを追加)

-- with 
    combined (part_id, rec_ord, rec_ts, rec_sum, del_ord, del_ts, del_sum) as (
     select part_id, order_id, ts, 
       sum(qty) over (partition by part_id order by ts, order_id), 
       null, cast(null as date), cast(null as number) 
     from received 
     union all 
     select part_id, null, cast(null as date), cast(null as number), 
       order_id, ts, 
       sum(qty) over (partition by part_id order by ts, order_id) 
     from delivered 
    ), 
    prep (part_id, rec_ord, del_ord, del_ts, qty_sum) as (
     select part_id, rec_ord, del_ord, del_ts, coalesce(rec_sum, del_sum) 
     from combined 
    ) 
select part_id, 
     last_value(rec_ord ignore nulls) over (partition by part_id 
               order by qty_sum desc) as rec_ord, 
     last_value(del_ord ignore nulls) over (partition by part_id 
               order by qty_sum desc) as del_ord, 
     last_value(del_ts ignore nulls) over (partition by part_id 
               order by qty_sum desc) as used_date, 
     qty_sum - lag(qty_sum, 1, 0) over (partition by part_id 
              order by qty_sum, del_ts) as used_qty 
from  prep 
order by qty_sum 
; 

出力

PART_ID REC_ORD DEL_ORD USED_DATE        USED_QTY 
------- ------- ------- ----------------------------------- ---------- 
11A4 0030 1200 18-MAR-15 04.30.00.000000000 PM    14 
11A4 0030 1210 23-MAR-15 10.30.00.000000000 AM    6 
11A4 0032 1210 23-MAR-15 10.30.00.000000000 AM    2 
11A4 0032 1220 23-MAR-15 11.30.00.000000000 AM    7 
11A4 0032 1230 23-MAR-15 11.30.00.000000000 AM    4 
11A4 0032 1230 23-MAR-15 11.30.00.000000000 AM    0 
11A4 0034 1240 26-MAR-15 03.00.33.000000000 PM    1 
11A4 0034 1250 26-MAR-15 04.45.11.000000000 PM    3 
11A4 0034 1260 27-MAR-15 10.00.33.000000000 AM    2 
11A4 0034 1270 03-APR-15 03.00.33.000000000 PM    12 
11A4 0036 1270 03-APR-15 03.00.33.000000000 PM    4 
11A4 0036              21 

12 rows selected. 

ノート: (1)ある時点で累積使用量が累積受信と正確に一致する場合には注意が必要です。すべての行がすべての中間結果に含まれていなければなりません。そうでなければ、出力に不良データがあります。しかし、これは(上記の出力で分かるように)「使用量」が0の数行で発生する可能性があります。この出力がどのように消費されたか(処理、レポートなどのために)それらはそのままであるか、または条件where used_qty > 0を有するさらなる外部クエリにおいて廃棄されてもよい。

(2)最後の行は、used_dateでなく、del_ordのない量21を示しています。これは、実際には両方のテーブルの最後の日付のpart_idの「現在の」在庫量であり、将来の使用のために利用可能です。これも必要ない場合は、外部クエリで削除することができます。テーブルの最後には、このような行が1つ以上存在することがあります。

+0

問題は私の使用表に注文番号がないことです。追加する方法がないためです。私は部分的に貧弱な設計を信じています。部品が到着すると、単にビンに入れられます。この時点では、シリアル番号やその他の種類のトラッキングは行われません。だから1つが注文されると、それはちょうどビンから引っ張られて送られ、使用記録は単に部品番号、数量、タイムスタンプを記録します。 – Zionmoose

関連する問題