【问题标题】:Groovy for loop that compares records from databaseGroovy for 循环比较数据库中的记录
【发布时间】:2020-07-24 04:53:46
【问题描述】:

我有一个包含 1 个包含数百条记录的表的数据库。我需要在 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
}
}
}
}

【问题讨论】:

  • 使用while 循环。请编辑您的问题并提供输入数据示例和预期结果。
  • 使用for循环
  • 我添加了一些例子
  • 请添加您尝试过的代码以及失败的原因(例如错误、堆栈跟踪、日志等),以便我们对其进行改进。

标签: database for-loop groovy


【解决方案1】:

以下代码将报告同一 port_nbr 和 pair 内长度变化 > 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

【讨论】:

  • 但是我有很多记录。 (所有记录都已按ports_nbr 排序)所以我必须比较第一条记录是否具有与第二条记录相同的port_nbr。然后我需要比较它们是否具有相同的对(pairA-D),然后我才能比较长度......示例 - 有 8 条记录,port_nbr 1......其中 6 条是pairA,其余的是pairB。所以我需要比较所有port_nbr 1,pairA之间的长度变化。然后我需要对 port_nbr 1,pairB 做同样的事情。当 port_nbr 1 中没有剩余时,它会继续对 port_nbr 2、3、4...等做同样的事情
  • 我已经更新了答案,假设您只比较每个端口的一对中的长度,并且您只对相邻行之间的长度变化感兴趣。
  • 嘿!我看到您在编写一些示例的地方添加了 rowSet。我有未知的记录列表,所以在这种情况下我需要做一些不同的事情
  • 我在我的代码中进行了选择,它从数据库中获取所有记录。看起来像这样 - dst_db1.eachRow("Select d.* from (select d.*, lead(length::float) over (partition by port_nbr, pair order by d.add_date) as next_length from diags d where length !='N/A')d")
  • 这行得通!没有更多的错误。它打印出来 - 密钥已更改。我搜索了它发生的原因,然后我看到了你的例子。我想我没有向你解释这个任务。我的想法是 - 第一个记录和第二个记录的差异,然后是第二个记录和第三个记录的差异,依此类推。在您的示例中,我看到您创建了将第一条记录与同一端口和对中的所有其他记录进行比较的脚本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多