Apache flink 为事件时间间隔联接找到多个rowtime字段

Apache flink 为事件时间间隔联接找到多个rowtime字段,apache-flink,flink-sql,Apache Flink,Flink Sql,我有两个流想要进行间隔连接,事件类型是如下定义的case类,tradeDate的类型是java.sql.Timestamp case class Stock(id: String, tradeDate: Timestamp, price: Double) case class StockNameChanging(id: String, name: String, tradeDate: Timestamp) 当我运行下面的应用程序时,抛出一个异常,如下所示,我不知道它在说什么以及如何解决问题 F

我有两个流想要进行间隔连接,事件类型是如下定义的case类,tradeDate的类型是
java.sql.Timestamp

case class Stock(id: String, tradeDate: Timestamp, price: Double)
case class StockNameChanging(id: String, name: String, tradeDate: Timestamp)
当我运行下面的应用程序时,抛出一个异常,如下所示,我不知道它在说什么以及如何解决问题

Found more than one rowtime field: [rt1, rt2] in the table that should be converted to a DataStream.
Please select the rowtime field that should be used as event-time timestamp for the DataStream by casting all other fields to TIMESTAMP.
org.apache.flink.table.api.TableException: Found more than one rowtime field: [rt1, rt2] in the table that should be converted to a DataStream.
Please select the rowtime field that should be used as event-time timestamp for the DataStream by casting all other fields to TIMESTAMP.
代码是:

val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
//Stock stream
val ds1 = env.addSource(new IntervalJoinStockSource(emitInterval = 0)).assignTimestampsAndWatermarks(new StockWatermarkGenerator(4000))

//StockNameChanging stream
val ds2 = env.addSource(new IntervalJoinStockNameChangingSource(emitInterval = 0)).assignTimestampsAndWatermarks(new StockNameChangingWatermarkGenerator(4000))
val tenv = StreamTableEnvironment.create(env)
tenv.createTemporaryView("s1", ds1, $"id", $"price", $"tradeDate".rowtime() as "rt1")
tenv.createTemporaryView("s2", ds2, $"id", $"name", $"tradeDate".rowtime() as "rt2")
tenv.from("s1").printSchema()
tenv.from("s2").printSchema()
val sql =
  """
  select s1.id, s2.name, s1.price, s1.rt1, s2.rt2
  from s1 join s2
  on s1.id = s2.id
  where s1.rt1 between s2.rt2 - interval '2' second and s2.rt2 + interval '2' second

  """.stripMargin(' ')

tenv.sqlQuery(sql).toAppendStream[Row].print()
env.execute()

每当Flink进行事件时间处理时,每个事件都需要一个事件时间戳。使用Flink SQL时,如果要进行事件时处理,则每行必须有一个rowtime属性,并且只能有一个。但是,查询创建的表有两个事件时间属性:s1.rt1和s2.rt2。Flink SQL运行时正在抱怨,因为它无法为此结果表中的行分配唯一的时间戳

因为在这个管道中没有进行任何进一步的基于事件时间的处理,所以实际上不需要将这些列视为行时列,所以可以选择其中一个或两个来转换为时间戳。我相信这样做会奏效:

选择
s1.id,s2.name,s1.price,将(s1.rt1作为时间戳)转换为t1,将(s2.rt2作为时间戳)转换为t2
从…起
s1连接s2
...

每当Flink进行事件时间处理时,每个事件都需要一个事件时间戳。使用Flink SQL时,如果要进行事件时处理,则每行必须有一个rowtime属性,并且只能有一个。但是,查询创建的表有两个事件时间属性:s1.rt1和s2.rt2。Flink SQL运行时正在抱怨,因为它无法为此结果表中的行分配唯一的时间戳

因为在这个管道中没有进行任何进一步的基于事件时间的处理,所以实际上不需要将这些列视为行时列,所以可以选择其中一个或两个来转换为时间戳。我相信这样做会奏效:

选择
s1.id,s2.name,s1.price,将(s1.rt1作为时间戳)转换为t1,将(s2.rt2作为时间戳)转换为t2
从…起
s1连接s2
...

感谢@david anderson的解释和帮助,这很有效!感谢@david anderson的解释和帮助,这很有效!