0

毎日、各アイテムに対して要求および発行されたアイテムの数を記録する必要があります。purchase_doc表は次のとおりです。

purchase_doc テーブル

テーブルには、次のrequested_itemsように要求されたアイテムが含まれています。

要求されたアイテム

テーブルには、次のmovementように要求されたアイテムが含まれています。

動き

必要な出力 (挿入するデータ) は次のとおりです。

data_to_insert

これを行う 1 つの方法は、最初の 2 つのクエリから発行およびリクエストされたアイテムをフェッチし、各アイテム ID に対して発行およびリクエストされたアイテムの配列を構築し、これらの値を次のように Daily_movement テーブルに挿入することです。

SELECT n.item_id AS n__item_id, SUM(n.qty) AS qty
FROM requested_items n LEFT JOIN purchase_doc doc ON n.doc_id = doc.id 
WHERE (doc.type = 'Item Request' AND doc.created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)) 
GROUP BY n.item_id

SELECT n.item_id AS item_id, SUM(n.qty) AS qty
FROM movement n LEFT JOIN purchase_doc doc ON n.doc_id = doc.id 
WHERE (doc.type = 'Store Issue' AND doc.created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)) 
GROUP BY n.item_id

これらの SELECT やその他の SELECT から、この方法で、このアイテムのリクエスト、問題などの数量を含む 1 日あたりのアイテムごとに 1 つの行を挿入する必要があります。

INSERT INTO daily_movement date, item_id, requested_qty, issued_qty VALUES ( NOW(), 23, 4, 5), ( NOW(), 25, 5, 5), ( NOW(), 113, 6, 8);

ただし、SELECT が多すぎて (アイテムごとに他のアクティビティも実行する必要があるため)、その後に挿入が続きます。

私の質問は次のとおりです。単一の SELECT ... INSERT ステートメントでこれを行うことは可能ですか。そうでない場合、誰かがこれを行うためのよりエレガントな方法を提案できますか

4

3 に答える 3

1

私はこれを考えていますが、単純化しすぎている可能性があります。

INSERT INTO `daily_movement`
  (`date`, `item_id`, `requested_qty`, `issued_qty`)
SELECT NOW(), `r`.`item_id`, SUM(`r`.`qty`), SUM(`m`.`qty`)
  FROM `purchase_doc` `d`
  JOIN `requested_items` `r`
    ON `r`.`doc_id` = `d`.`id`
  LEFT JOIN `movement` `m`
    ON `m`.`doc_id` = `d`.`id`
WHERE
    (`d`.`type` = 'Item Request' OR `d`.`type` = 'Store Issue')
  AND
    `d`.`created_at` > DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY `r`.`item_id`

編集

これが私の最終的な答えですUNION.MySQLの欠如を回避するのは厄介ですFULL OUTER JOIN:

INSERT INTO `daily_movement`
  (`date`, `item_id`, `week_no`, `requested_qty`, `issued_qty`)
SELECT *
FROM (
  (
    SELECT COALESCE(`r`.`item_id`, `a`.`item_id`) AS `item_id`, CURDATE() AS `date`, NULL AS `week_no`, SUM(`r`.`qty`) AS `requests`, COALESCE(`a`.`issued`, 0) AS `issued`
    FROM `purchase_doc` `d`
    LEFT JOIN `requested_items` `r`
      ON `r`.`doc_id` = `d`.`id` 
    LEFT JOIN (
      SELECT `m`.`item_id`, SUM(`m`.`qty`) AS `issued`
      FROM `purchase_doc` `d`
      JOIN `movement` `m`
        ON `m`.`doc_id` = `d`.`id` 
      WHERE `d`.`type` = 'Store Issue'
        AND `d`.`created_at` > DATE_SUB(NOW(), INTERVAL 24 HOUR)
      GROUP BY `m`.`item_id`
    ) `a`
      ON `a`.`item_id` = `r`.`item_id`
    WHERE `d`.`type` = 'Material Requisition'
      AND `d`.`created_at` > DATE_SUB(NOW(), INTERVAL 24 HOUR)
    GROUP BY `r`.`item_id`
  ) UNION DISTINCT (
    SELECT COALESCE(`m`.`item_id`, `a`.`item_id`) AS `item_id`, CURDATE() AS `date`, NULL AS `week_no`, COALESCE(`a`.`requests`, 0) AS `requests`, SUM(`m`.`qty`) AS `issued`
    FROM `purchase_doc` `d`
    LEFT JOIN `movement` `m`
      ON `m`.`doc_id` = `d`.`id` 
    LEFT JOIN (
      SELECT `r`.`item_id`, SUM(`r`.`qty`) AS `requests`
      FROM `purchase_doc` `d`
      JOIN `requested_items` `r`
        ON `r`.`doc_id` = `d`.`id` 
      WHERE `d`.`type` = 'Material Requisition'
        AND `d`.`created_at` > DATE_SUB(NOW(), INTERVAL 24 HOUR)
      GROUP BY `r`.`item_id`
    ) `a`
      ON `a`.`item_id` = `m`.`item_id`
    WHERE `d`.`type` = 'Store Issue'
      AND `d`.`created_at` > DATE_SUB(NOW(), INTERVAL 24 HOUR)
    GROUP BY `m`.`item_id`
  )
  ORDER BY `item_id`
) `u`

http://sqlfiddle.com/#!2/3923d/13

于 2012-07-25T15:14:48.110 に答える
0

ここまたはここでユニオン演算子を使用して、単一の選択ですべての結果を取得できます

于 2012-07-25T14:49:34.160 に答える
0

次のようなクエリを使用できます-

編集:

INSERT INTO daily_movement(date, item_id, requested_qty, issued_qty)
SELECT i.item_id, SUM(ri.qty) requested_qty, SUM(m.qty) issued_qty FROM
  (SELECT item_id FROM requested_items UNION SELECT item_id FROM movement) i
  LEFT JOIN (
    SELECT n.item_id, n.qty
    FROM requested_items n LEFT JOIN purchase_doc doc ON n.doc_id = doc.id 
    WHERE doc.type = 'Item Request' AND doc.created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)
  ) ri
  ON ri.item_id = i.item_id
  LEFT JOIN (
    SELECT n.item_id, n.qty
    FROM movement n LEFT JOIN purchase_doc doc ON n.doc_id = doc.id 
    WHERE doc.type = 'Store Issue' AND doc.created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)
  ) m
  ON m.item_id = i.item_id
GROUP BY
  i.item_id;
于 2012-07-25T14:58:02.303 に答える