根据早期数据SQL识别特定数据

时间:2018-08-13 20:44:22

标签: sql db2

我目前正在使用DB2数据库进行查询,该数据库需要确定特定日期不同位置之间人员的特定流动。通常,这不是什么大问题,但是在这种特殊情况下,所讨论的运动取决于之前发生的某些运动。我对SQL还是很陌生,所以这使我无所适从。

作为一个例子,想像这样的东西:
我们正在从名为Profile和ExternalMovement的表中调用数据。个人资料包含名称,ID和其他标识数据,而外部运动包含日期,位置和移动。有编号为1-3的位置,以及移动类型为A-C。假设我们的表中包含以下数据:

| Name  | Date       | Location | Movement |
|-------|------------|----------|----------|
| Kelly | 01/03/2013 | 2        | A        |
| Kelly | 01/02/2013 | 3        | C        |
| Mark  | 01/02/2013 | 2        | A        |
| Mark  | 01/03/2013 | 2        | B        |
| Mark  | 01/09/2013 | 1        | A        |
| Kelly | 01/11/2013 | 1        | C        |
| Kelly | 01/12/2013 | 3        | B        |
| Mark  | 01/14/2013 | 3        | C        |

我想做的是能够调出所有C类型的运动,而最后一次运动也不是C类型,结果是:

| Name  | Date       | Location | Movement |
|-------|------------|----------|----------|
| Kelly | 01/02/2013 | 3        | C        |
| Mark  | 01/14/2013 | 3        | C        | 

要使事情变得更加有趣,万一任何解决方案都需要写表,我没有表写特权,因此必须采取变通方法。我当前的代码迭代在一定程度上可以正常工作,但是据我所知,它并不是很有效。本质上,我指定要提取数据的代码,然后在同一数据集上执行select(max),将其限制为之前指定的日期。

SELECT A.Name, EX.Date, EX.Location, EX.Movement From Profile A
JOIN ExternalMovement EX ON EX.ID = A.ID AND Movement = 'C'
JOIN ExternalMovement PRIOR on PRIOR.ID = EX.ID
AND PRIOR.Date = (SELECT MAX(PRIOR1.Date) ON ExternalMovement PRIOR1 
WHERE PRIOR1.ID = EX.ID AND PRIOR1.Date < EX.Date AND PRIOR1.Movement <> 'C')

现在,真实的事情当然要复杂得多了,如有必要,我可以发布实际代码,但我希望这个简单的示例足以回答问题。

1 个答案:

答案 0 :(得分:0)

使用lag()

select pem.*
from (select . . . ,
             lag(em.movement) over (partition by p.name order by em.date) as prev_movement
      from Profile p join
           ExternalMovement em
           on em.ID = p.ID
     ) pem
where movement = 'C' and (prev_movement <> 'C' or prev_movement is null);