我是Talend Open Studio的初学者,我正尝试在下面进行转换。
来自包含以下内容的SQL表:
DeltaStock Date
------------------------
+50 (initial stock) J0
+80 J1
-30 J2
... ...
我想制作这张表:
Stock Date
-----------
50 J0
130 J1
100 J2
... ...
您认为使用TOS可以实现这一目标吗?我想过使用tAggregateRow,但我发现它并不适合我的问题。
答案 0 :(得分:0)
使用tMemorizeRows组件可能有一种更简单的方法,但首先想到的是使用globalMap存储滚动总和。
在Talend中,可以在globalMap中存储一个对象(任何值或任何类型),以便以后可以在作业中检索它。如果您使用tFlowToIterate组件,它将自动使用,该组件允许您从globalMap检索正在迭代的该行的值。
非常基本的示例作业可能如下所示:
在这里我们有一个tJava组件,它只使用以下代码初始化globalMap中的滚动总和:
//Initialise the rollingSum global variable
globalMap.put("rollingSum", 0);
在此之后,我们将这个组件连接到SubjobOk,以确保我们只有在设法将rollingSum
放入globalMap时才会继续。
然后我使用tFixedFlowInput组件提供我的数据,这使我可以轻松地对此示例作业的某些值进行硬编码。您可以使用任何输入轻松替换它。我已经使用了问题中的示例输入数据:
然后我们使用tJavaRow处理数据,它将逐行对数据进行一些转换。我使用了以下代码,该代码适用于此示例:
//Initialise the operator and the value variables
String operator = "";
Integer value = 0;
//Get the current rolling sum
Integer rollingSum = (Integer) globalMap.get("rollingSum");
//Extract the operator
Pattern p = Pattern.compile("^([+-])([0-9]+)$");
Matcher m = p.matcher(input_row.deltaStock);
//If we have any matches from the regular expression search then extract the operator and the value
if (m.find()) {
operator = m.group(1);
value = Integer.parseInt(m.group(2));
}
//Conditional to use the operator
if ("+".equals(operator)) {
rollingSum += value;
} else if ("-".equals(operator)) {
rollingSum -= value;
} else {
System.out.println("The operator provided wasn't a + or a -");
}
//Put the new rollingSum back into the globalMap
globalMap.put("rollingSum", rollingSum);
//Output the data
output_row.stock = rollingSum;
output_row.date = input_row.date;
那里有很多事情,但基本上它是从globalMap获取当前rollingSum
开始的。
接下来,它使用正则表达式将deltaStock
字符串拆分为operator
和value
。由此,它使用提供的运算符(加号或减号)将deltaStock
添加到rollingSum
或从deltaStock
中减去rollingSum
。
然后将新的rollingSum
添加回globalMap并输出stock
和date
的两列(未更改)。
在我的示例作业中,然后使用tLogRow输出数据,tLogRow将数据的值打印到控制台。我通常在其中选择表格格式选项,在这种情况下,我得到以下输出:
.-----+----.
|tLogRow_8 |
|=----+---=|
|stock|date|
|=----+---=|
|50 |J0 |
|130 |J1 |
|100 |J2 |
'-----+----'
这应该是你想要的。
答案 1 :(得分:0)
您应该可以在Talend Open Studio中完成。
我在这里附上一个带有JOB的图像,tJavaRow的内容和执行结果。
我离开了tFixedFlowInput,用于模拟输入一个tJDBCInput,你应该用它来读取数据库中的数据。希望您可以为您的数据库使用特定的tXXXInput而不是通用的JDBC。
这是tJavaRow中的一些简单代码。
//Code generated according to input schema and output schema
output_row.delta = input_row.delta;
output_row.date = input_row.date;
output_row.rollingSum =
Integer.parseInt(globalMap.get("rollingSum").toString());
int delta = Integer.parseInt(input_row.delta);
output_row.rollingSum += delta;
// Save rolling SUM for next round
globalMap.put("rollingSum", output_row.rollingSum);
请注意parseInt()中的异常。你应该以你认为正确的方式处理它们。 在我的项目中,我通常有一个SafeParse库,它不会抛出异常但会返回一个默认值,我可以将其与要解析的值一起传递。