首页 > 解决方案 > Groovy for 循环比较数据库中的记录

问题描述

我有一个包含数百条记录的表的数据库。我需要在 groovy 脚本中创建一个 for 循环,将第一条记录与第二条记录、第二条记录与第三条记录等进行比较。我需要比较记录之间的长度变化并打印出所有高于 30 的变化。示例 - 第一条记录 30m ,第二条记录40m,第三条记录100m。它将打印出第二个第三个记录。我不知道表中的记录数量,所以我不知道如何创建 for 循环。有什么建议么?记录也有ip。每个 ip 可以多次,我需要比较每个 ip 中的所有记录。

记录 1:

port_nbr | 1                          
pair     | pairA
length   | 30.00
add_date | 2020-06-16 00:01:13.237164

记录2:

port_nbr | 1                              
pair     | pairA
length   | 65.00
add_date | 2020-06-16 00:02:13.237164

记录 3:

port_nbr | 2                              
pair     | pairc
length   | 65.00
add_date | 2020-06-16 00:02:13.237164

我希望 for 循环检查当前记录 port_nbr 是否与下一条记录相同,如果是,则检查对是否相同,如果相同,则比较长度是否更改为 30+m。在这种情况下,它将输出 1/2 记录中有 30+m 的变化。输出后,比较第二条记录和第三条记录。但是它们没有相同的 port_nbr 和 pair,所以我希望它再次开始比较所有为 2 的 port_nbr 与所有以下记录。甚至可能有 10 条记录,port_nbr 为 1,但对不同。我还需要检查对,然后才比较长度。

我此时的代码:

import java.sql.*;
import groovy.sql.Sql

class Main{
static void main(String[] args) {

def dst_db1 = Sql.newInstance('connection.........')
dst_db1.getConnection().setAutoCommit(false)


def sql = (" select d.* from (select d.*, lead((case when length <> 'N/A' then length else length_to_fault end)::float) over (partition by port_nbr, pair order by port_nbr, pair, d.add_date) as lengthh from diags d)d limit 10")

def lastRow = [id:-1, port_nbr:-1, pair:'', lengthh:-1.0]
dst_db1.eachRow( sql ) {row ->

if( row.port_nbr == lastRow.port_nbr && row.pair == lastRow.pair){
BigDecimal lengthChange =
new BigDecimal(row.lengthh ? row.lengthh : 0 ) - new BigDecimal(lastRow.lengthh ? lastRow.lengthh :0 )

if( lengthChange > 30.0){
print "Port ${row.port_nbr}, ${row.pair} length change: $lengthChange"
println "/tbetween row ID ${lastRow.id} and ${row.id}"
}
lastRow = row
}else{
println "Key Changed"
lastRow = row
}
}
}
}

标签: databasefor-loopgroovy

解决方案


以下代码将报告同一 port_nbr 和对内的长度变化 > 30。

def sql = 'Your SQL here.' // Should include "order by pair, port_nbr, date"

def lastRow = [id:-1, port_nbr:-1, pair:'', length:-1.0]
dst_db1.eachRow( sql ) { row ->

  if ( row.port_nbr == lastRow.port_nbr && row.pair == lastRow.pair ) {
    BigDecimal lengthChange = 
      new BigDecimal( row.length ) - new BigDecimal( lastRow.length )

    if ( lengthChange > 30.0 ) {
        print "Port ${row.port_nbr}, ${row.pair} length change: $lengthChange"
        println "\tbetween row ID ${lastRow.id} and ${row.id}"
    }
    lastRow = row
  } else {
    println "Key changed"
    lastRow = row
  }
}

为了在没有数据库的情况下运行上面的代码,我在它前面加上了这个测试代码:

class DstDb1 {

  def eachRow ( sql, closure ) {
    rows.each( closure )
  }
  
  def rows = [
    [id: 1, port_nbr: 1, pair: 'pairA', length:  30.00 ],
    [id: 2, port_nbr: 1, pair: 'pairA', length:  65.00 ],
    [id: 3, port_nbr: 1, pair: 'pairA', length:  70.00 ],
    [id: 4, port_nbr: 1, pair: 'pairA', length:  75.00 ],
    [id: 5, port_nbr: 1, pair: 'pairB', length: 130.00 ],
    [id: 6, port_nbr: 1, pair: 'pairB', length: 165.00 ],
    [id: 7, port_nbr: 1, pair: 'pairB', length: 170.00 ],
    [id: 8, port_nbr: 1, pair: 'pairB', length: 175.00 ],
    [id: 9, port_nbr: 2, pair: 'pairC', length: 230.00 ],
    [id:10, port_nbr: 2, pair: 'pairC', length: 265.00 ],
    [id:11, port_nbr: 2, pair: 'pairC', length: 270.00 ],
    [id:12, port_nbr: 2, pair: 'pairC', length: 350.00 ]
  ]
}

DstDb1 dst_db1 = new DstDb1()

运行测试给出以下结果:

Key changed
Port 1, pairA length change: 35 between row ID 1 and 2
Key changed
Port 1, pairB length change: 35 between row ID 5 and 6
Key changed
Port 2, pairC length change: 35 between row ID 9 and 10
Port 2, pairC length change: 80 between row ID 11 and 12

推荐阅读