具有可变记录的SQL增量计算

具有可变记录的SQL增量计算,sql,postgresql,Sql,Postgresql,我正在计算calc_表批量运行之间的金额差异,并将其存储在delta_表中。每次批处理运行的calc_表中的记录数可能会有所不同 我可以计算差异,但我不确定如何处理新记录或已删除记录,因为SQL中的连接将不同。我相信我需要使用完全联接,但在构造SQL查询时遇到了问题 注意:批处理id并不总是递增1。查询应该在calc_表中,因为这是存储金额的地方。delta_表将包含calc_表中金额之间的差异 这是我当前的SQL:我正在使用PostgreSQL select c2.batch_id, c2.c

我正在计算calc_表批量运行之间的金额差异,并将其存储在delta_表中。每次批处理运行的calc_表中的记录数可能会有所不同

我可以计算差异,但我不确定如何处理新记录或已删除记录,因为SQL中的连接将不同。我相信我需要使用完全联接,但在构造SQL查询时遇到了问题

注意:批处理id并不总是递增1。查询应该在calc_表中,因为这是存储金额的地方。delta_表将包含calc_表中金额之间的差异

这是我当前的SQL:我正在使用PostgreSQL

select c2.batch_id, c2.c_id, c2.date, 
       (c2.amount1 - c1.amount1) as amount1, (c2.amount2 - c1.amount2) as amount2
from calc_table c1 inner join calc_table c2 on c1.c_id = c2.c_id 
where c1.batch_id = 100 and c2.batch_id = 101

* c1.batch_id and c2.batch_id are PARAMETERS.
这给了我所有预期的c_id,包括删除的和新的记录。但是我不能正确地构造它来给出delta计算的预期结果

SELECT coalesce(c2.c_id, c1.c_id) as c_id
FROM
  (select * from calc_table where batch_id = 100) c1
FULL OUTER JOIN
  (select * from calc_table where batch_id = 101) c2
ON c1.id = c2.id
group by coalesce(c2.c_id, c1.c_id);
这是计算表的第一次运行:批处理id=100

calc_table:
-----------------------------------------------------
id | batch_id | c_id | date       | amount1 | amount2
-----------------------------------------------------
1  | 100      | C001 | 2017-03-01 | 100     | 200 
2  | 100      | C002 | 2017-03-01 | 100     | 200 
3  | 100      | C003 | 2017-03-01 | 100     | 200 
如果用户再次运行:batch_id=101

4  | 101      | C001 | 2017-03-01 | 200     | 200 
5  | 101      | C002 | 2017-03-01 | 150     | 220 
6  | 101      | C003 | 2017-03-01 | 170     | 250 
7  | 101      | C004*| 2017-03-01 | 210     | 250  

* C004 is a new record
应计算批次id 101减去100之间的增量,并将其存储在增量表中:

delta_table:
------------------------------------------------------
id | batch_id | c_id | date       | amount1 | amount2 
------------------------------------------------------
1  | 101      | C001 | 2017-03-01 | 100     | 0       
2  | 101      | C002 | 2017-03-01 | 50      | 20      
3  | 101      | C003 | 2017-03-01 | 70      | 50      
4  | 101      | C004 | 2017-03-01 | 210     | 250     
* Rows 1-4 (same as before), new delta = id 5-8

delta_table:
------------------------------------------------------
id | batch_id | c_id | date       | amount1 | amount2 
------------------------------------------------------
1  | 101      | C001 | 2017-03-01 | 100     | 0       
2  | 101      | C002 | 2017-03-01 | 50      | 20      
3  | 101      | C003 | 2017-03-01 | 70      | 50      
4  | 101      | C004 | 2017-03-01 | 210     | 250     

5  | 104      | C001 | 2017-03-01 | 0       | 0       
6  | 104      | C002 | 2017-03-01 | 250     | -20     
7  | 104      | C003 | 2017-03-01 | 230     | -30     
8  | 104      | C004 | 2017-03-01 | -210    | -250    
如果用户再次运行:批处理id=104,id 8-10

* Rows 1-7 (same as before)

calc_table:
-----------------------------------------------------
id | batch_id | c_id | date       | amount1 | amount2
-----------------------------------------------------
1  | 100      | C001 | 2017-03-01 | 100     | 200 
2  | 100      | C002 | 2017-03-01 | 100     | 200 
3  | 100      | C003 | 2017-03-01 | 100     | 200 
4  | 101      | C001 | 2017-03-01 | 200     | 200 
5  | 101      | C002 | 2017-03-01 | 150     | 220 
6  | 101      | C003 | 2017-03-01 | 170     | 250 
7  | 101      | C004 | 2017-03-01 | 210     | 250  

8  | 104      | C001 | 2017-03-01 | 200     | 200 
9  | 104      | C002 | 2017-03-01 | 400     | 200 
10 | 104      | C003 | 2017-03-01 | 400     | 220 

* Note: C004 was deleted
应计算批次id 104减去101之间的增量,并将其存储在增量表中:

delta_table:
------------------------------------------------------
id | batch_id | c_id | date       | amount1 | amount2 
------------------------------------------------------
1  | 101      | C001 | 2017-03-01 | 100     | 0       
2  | 101      | C002 | 2017-03-01 | 50      | 20      
3  | 101      | C003 | 2017-03-01 | 70      | 50      
4  | 101      | C004 | 2017-03-01 | 210     | 250     
* Rows 1-4 (same as before), new delta = id 5-8

delta_table:
------------------------------------------------------
id | batch_id | c_id | date       | amount1 | amount2 
------------------------------------------------------
1  | 101      | C001 | 2017-03-01 | 100     | 0       
2  | 101      | C002 | 2017-03-01 | 50      | 20      
3  | 101      | C003 | 2017-03-01 | 70      | 50      
4  | 101      | C004 | 2017-03-01 | 210     | 250     

5  | 104      | C001 | 2017-03-01 | 0       | 0       
6  | 104      | C002 | 2017-03-01 | 250     | -20     
7  | 104      | C003 | 2017-03-01 | 230     | -30     
8  | 104      | C004 | 2017-03-01 | -210    | -250    
也许可以尝试完全加入

假设为其计算增量的批次id始终为1。大概是这样的:

SELECT COALESCE(new.batch_id, old_padded_with_deleted.batch_id) AS batch_id,
       COALESCE(new.c_id, old_padded_with_deleted.c_id) AS c_id,
       COALESCE(new.date, old_padded_with_deleted.date) AS date, --new.amount1, old_padded_with_deleted.amount1,
       CASE WHEN new.amount1 IS NULL THEN -old_padded_with_deleted.amount1 ELSE (new.amount1 - coalesce(old_padded_with_deleted.amount1, 0)) END AS amount1,
       CASE WHEN new.amount2 IS NULL THEN -old_padded_with_deleted.amount2 ELSE (new.amount2 - coalesce(old_padded_with_deleted.amount2, 0)) END AS amount2
FROM calc_table new
FULL JOIN (
  SELECT coalesce(old.batch_id, deleted.batch_id)+1 AS batch_id, coalesce(old.c_id, deleted.c_id) AS c_id, coalesce(old.date, deleted.date) AS date,
         coalesce(old.amount1, deleted.amount1) AS amount1, coalesce(old.amount2, deleted.amount2) AS amount2
  FROM delta_table AS deleted
  FULL JOIN calc_table AS old ON old.batch_id = deleted.batch_id AND old.c_id = deleted.c_id
) AS old_padded_with_deleted ON old_padded_with_deleted.c_id = new.c_id
                        AND old_padded_with_deleted.batch_id = new.batch_id
WHERE
  new.batch_id = 101 OR old_padded_with_deleted.batch_id = 101
也许可以尝试完全加入

假设为其计算增量的批次id始终为1。大概是这样的:

SELECT COALESCE(new.batch_id, old_padded_with_deleted.batch_id) AS batch_id,
       COALESCE(new.c_id, old_padded_with_deleted.c_id) AS c_id,
       COALESCE(new.date, old_padded_with_deleted.date) AS date, --new.amount1, old_padded_with_deleted.amount1,
       CASE WHEN new.amount1 IS NULL THEN -old_padded_with_deleted.amount1 ELSE (new.amount1 - coalesce(old_padded_with_deleted.amount1, 0)) END AS amount1,
       CASE WHEN new.amount2 IS NULL THEN -old_padded_with_deleted.amount2 ELSE (new.amount2 - coalesce(old_padded_with_deleted.amount2, 0)) END AS amount2
FROM calc_table new
FULL JOIN (
  SELECT coalesce(old.batch_id, deleted.batch_id)+1 AS batch_id, coalesce(old.c_id, deleted.c_id) AS c_id, coalesce(old.date, deleted.date) AS date,
         coalesce(old.amount1, deleted.amount1) AS amount1, coalesce(old.amount2, deleted.amount2) AS amount2
  FROM delta_table AS deleted
  FULL JOIN calc_table AS old ON old.batch_id = deleted.batch_id AND old.c_id = deleted.c_id
) AS old_padded_with_deleted ON old_padded_with_deleted.c_id = new.c_id
                        AND old_padded_with_deleted.batch_id = new.batch_id
WHERE
  new.batch_id = 101 OR old_padded_with_deleted.batch_id = 101

使用以下SQL解决了此问题:

select c1.c_id, 
sum(case when c1.batch_id = 100 then (c1.amount1 * -1) else (c1.amount1 * 1) end) as amount1
from calc_table c1
where c1.batch_id = 100 or c1.batch_id = 101
group by c1.c_id

使用以下SQL解决了此问题:

select c1.c_id, 
sum(case when c1.batch_id = 100 then (c1.amount1 * -1) else (c1.amount1 * 1) end) as amount1
from calc_table c1
where c1.batch_id = 100 or c1.batch_id = 101
group by c1.c_id

我可以计算差异,但我不确定如何处理新的或删除的记录。-您不必在SELECT中处理类似的事情。如果您只想将select的每个输出存储在delta_表中,为什么不直接从delta_表中删除;在再次存储新结果之前?-此外,只有这些信息,将结果存储在单独的表中似乎不太可能有任何帮助。您可以使用游标、临时表甚至您的客户端应用程序来处理这些差异。我给出的答案应该与您期望的结果相匹配。不确定是否会通知您答案,因为我已删除并取消删除了它。我可以计算差异,但我不确定如何处理新记录或删除的记录。-您不必在SELECT中处理类似的事情。如果您只想将select的每个输出存储在delta_表中,为什么不直接从delta_表中删除;在再次存储新结果之前?-此外,只有这些信息,将结果存储在单独的表中似乎不太可能有任何帮助。您可以使用游标、临时表甚至您的客户端应用程序来处理这些差异。我给出的答案应该与您期望的结果相匹配。不确定是否会通知您答案,因为我已删除并取消删除它。它不起作用,1批次id并不总是递增1。金额之间的差异是错误的——应该在calc_表中计算,而不是从delta_表中计算。3我得到的是删除的记录,但不是添加的记录。这不起作用,1批次id并不总是递增1。金额之间的差异是错误的——应该在calc_表中计算,而不是从delta_表中计算。3我得到的是删除的记录,而不是添加的记录。