-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 倍(2 获取最新的id,2 获取id之前的):

最新突变

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 回答