-1

アイテムの現在の金額を監視するテーブルから、最新の受領金額を取得しようとしています。

現在、各- +トランザクションではなく、現在の合計金額が保存されます。レポートが生成されたら、現在、最新の受領額、最新の削除額を確認する必要があります。次に、指定された時間枠で同じことを行うことができます。省略されたタイムスタンプ列を使用して、1 月に受け取ったアイテムなど。

テーブル レイアウト

 id | item_id | amount  
 1  |  20     |   5    # +5  (initial)
 2  |  30     |   1    # +1  (initial)
 3  |  20     |   20   # +15 
 4  |  15     |   10   # +10 (initial/latest)
 5  |  20     |   25   # +5  (latest)
 6  |  20     |   4    # -21 
 7  |  30     |   2    # -1  
 8  |  30     |   5    # +3  (latest)
 9  |  15     |   2    # -8  
10  |  15     |   1    # -1  

クエリの例

SELECT
   t1.item_id,
   t1.amount as amount,
   IFNULL(t2.amount, 0) as previous_amount,
   IFNULL(t1.amount - IFNULL(t2.amount, 0), NULL) as received_amount
FROM
   items AS t1
LEFT JOIN
   items AS t2
ON
    t1.item_id = t2.item_id
AND
    t1.id > t2.id #Get the record before the current t1.id

返された結果

item_id | amount | previous_amount | received_amount | matching_ids    
20      | 5      |    0            |    5            |    1, NULL    
30      | 1      |    0            |    1            |    2, NULL    
20      | 20     |    5            |    15           |    3, 1    
15      | 10     |    0            |    10           |    4, NULL    
20      | 25     |    5            |    20           |    5, 1    
20      | 25     |    20           |    5            |    5, 3    
20      | 4      |    5            |    -1           |    6, 1    
20      | 4      |    20           |    -16          |    6, 3    
20      | 4      |    25           |    -21          |    6, 5    
30      | 2      |    1            |    1            |    7, 2    
30      | 5      |    1            |    4            |    8, 2    
30      | 5      |    2            |    3            |    8, 7    
15      | 2      |    10           |    -8           |    9, 4    
15      | 1      |    10           |    -9           |    10, 4    
15      | 1      |    2            |    -1           |    10, 9    

望ましい結果は、最新の受領額がある場合のみです。

望ましい結果

#last_received_amount = (t1.amount - t2.amount)
item_id | latest_received_amount | matching_ids
   20   |    5                   |   5, 3
   15   |    10                  |   4, null
   30   |    3                   |   8, 7

クエリは、個々のトランザクションを使用してリファクタリングされるまで、暫定的な修正として使用することを目的としています。

4

1 に答える 1

2

クエリ内のテーブルの 4 倍 (最新のものを取得するid場合は 2、idそれ以前のものを取得する場合は 2):

最新の突然変異

SELECT
   t1.item_id,
   t1.amount as amount,
   IFNULL(t3.amount, 0) as previous_amount,
   IFNULL(t1.amount - IFNULL(t3.amount, 0), NULL) as received_amount,
   CONCAT_WS(', ',t1.id, t3.id)
FROM items t1
LEFT JOIN items t2
  ON  t1.item_id = t2.item_id
  AND t2.id > t1.id
LEFT JOIN items t3
  ON  t1.item_id = t3.item_id
  AND t3.id != t1.id
LEFT JOIN items t4
  ON  t1.item_id = t4.item_id
  AND t4.id > t3.id
  AND t4.id != t1.id
WHERE 
    t1.category_id IN( '1', '2', '3' )
    AND t2.id IS NULL
    AND t4.id IS NULL;


+---------+--------+-----------------+-----------------+------------------------------+
| item_id | amount | previous_amount | received_amount | CONCAT_WS(', ',t1.id, t3.id) |
+---------+--------+-----------------+-----------------+------------------------------+
|      20 |      4 |              25 |             -21 | 6, 5                         |
|      30 |      5 |               2 |               3 | 8, 7                         |
|      15 |      1 |               2 |              -1 | 10, 9                        |
+---------+--------+-----------------+-----------------+------------------------------+

ポジティブミューテーション

  SELECT
    t1.item_id,
    t1.amount as amount,
    IFNULL(t2.amount, 0) as previous_amount,
    IFNULL(t1.amount - IFNULL(t2.amount, 0), NULL) as received_amount,
    CONCAT_WS(', ',t1.id, t2.id)
  FROM items t1
  LEFT JOIN items t2
    ON  t1.item_id = t2.item_id
    AND t2.id < t1.id
    AND t2.amount < t1.amount
  LEFT JOIN items t3
    ON  t2.item_id = t3.item_id
    AND t3.id > t2.id
    AND t3.id < t1.id
  LEFT JOIN items noprev
    ON  t1.item_id = noprev.item_id
    AND noprev.id < t1.id
    AND noprev.amount > t1.amount
  WHERE
      t1.category_id IN( '1', '2', '3' )
      AND t3.id IS NULL
      AND (noprev.id IS NULL OR t2.id IS NOT NULL)

+---------+--------+-----------------+-----------------+------------------------------+
| item_id | amount | previous_amount | received_amount | CONCAT_WS(', ',t1.id, t2.id) |
+---------+--------+-----------------+-----------------+------------------------------+
|      20 |      5 |               0 |               5 | 1                            |
|      30 |      1 |               0 |               1 | 2                            |
|      20 |     20 |               5 |              15 | 3, 1                         |
|      15 |     10 |               0 |              10 | 4                            |
|      20 |     25 |              20 |               5 | 5, 3                         |
|      30 |      2 |               1 |               1 | 7, 2                         |
|      30 |      5 |               2 |               3 | 8, 7                         |
+---------+--------+-----------------+-----------------+------------------------------+

最新の陽性変異

SELECT increases.item_id, increases.amount, increases.previous_amount,increases.received_amount,increases.ids
FROM (
  SELECT
    t1.id,
    t1.item_id,
    t1.amount as amount,
    IFNULL(t2.amount, 0) as previous_amount,
    IFNULL(t1.amount - IFNULL(t2.amount, 0), NULL) as received_amount,
    CONCAT_WS(', ',t1.id, t2.id) as ids
  FROM items t1
  LEFT JOIN items t2
    ON  t1.item_id = t2.item_id
    AND t2.id < t1.id
    AND t2.amount < t1.amount
  LEFT JOIN items t3
    ON  t2.item_id = t3.item_id
    AND t3.id > t2.id 
    AND t3.id < t1.id
  LEFT JOIN items noprev
    ON  t1.item_id = noprev.item_id
    AND noprev.id < t1.id
    AND noprev.amount > t1.amount
  WHERE 
      t1.category_id IN( '1', '2', '3' )
      AND t3.id IS NULL
      AND (noprev.id IS NULL OR t2.id IS NOT NULL)
) increases
LEFT JOIN (SELECT
    t1.id,
    t1.item_id
  FROM items t1
  JOIN items t2
    ON  t1.item_id = t2.item_id
    AND t2.id < t1.id
    AND t2.amount < t1.amount
  LEFT JOIN items t3
    ON  t2.item_id = t3.item_id
    AND t3.id > t2.id 
    AND t3.id < t1.id
  WHERE 
      t1.category_id IN( '1', '2', '3' )
      AND t3.id IS NULL
) later_increases
  ON later_increases.item_id = increases.item_id
  AND later_increases.id > increases.id
WHERE later_increases.id IS NULL;

+---------+--------+-----------------+-----------------+------+
| item_id | amount | previous_amount | received_amount | ids  |
+---------+--------+-----------------+-----------------+------+
|      15 |     10 |               0 |              10 | 4    |
|      20 |     25 |              20 |               5 | 5, 3 |
|      30 |      5 |               2 |               3 | 8, 7 |
+---------+--------+-----------------+-----------------+------+

これは....これには一時テーブルを使用することをお勧めします。

于 2013-03-28T18:52:44.267 に答える