我们可以使用Talend Open Studio聚合动态行数

时间:2014-10-22 10:58:29

标签: etl talend

我是Talend Open Studio的初学者,我正尝试在下面进行转换。

来自包含以下内容的SQL表:

DeltaStock          Date 
------------------------
+50 (initial stock) J0    
+80                 J1    
-30                 J2
...                 ...

我想制作这张表:

Stock  Date
-----------
50     J0             
130    J1
100    J2 
...    ...

您认为使用TOS可以实现这一目标吗?我想过使用tAggregateRow,但我发现它并不适合我的问题。

2 个答案:

答案 0 :(得分:0)

使用tMemorizeRows组件可能有一种更简单的方法,但首先想到的是使用globalMap存储滚动总和。

在Talend中,可以在globalMap中存储一个对象(任何值或任何类型),以便以后可以在作业中检索它。如果您使用tFlowToIterate组件,它将自动使用,该组件允许您从globalMap检索正在迭代的该行的值。

非常基本的示例作业可能如下所示:

Sample job layout

在这里我们有一个tJava组件,它只使用以下代码初始化globalMap中的滚动总和:

//Initialise the rollingSum global variable
globalMap.put("rollingSum", 0);

在此之后,我们将这个组件连接到SubjobOk,以确保我们只有在设法将rollingSum放入globalMap时才会继续。

然后我使用tFixedFlowInput组件提供我的数据,这使我可以轻松地对此示例作业的某些值进行硬编码。您可以使用任何输入轻松替换它。我已经使用了问题中的示例输入数据:

tFixedFlowInput configuration and sample data

然后我们使用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字符串拆分为operatorvalue。由此,它使用提供的运算符(加号或减号)将deltaStock添加到rollingSum或从deltaStock中减去rollingSum

然后将新的rollingSum添加回globalMap并输出stockdate的两列(未更改)。

在我的示例作业中,然后使用tLogRow输出数据,tLogRow将数据的值打印到控制台。我通常在其中选择表格格式选项,在这种情况下,我得到以下输出:

.-----+----.
|tLogRow_8 |
|=----+---=|
|stock|date|
|=----+---=|
|50   |J0  |
|130  |J1  |
|100  |J2  |
'-----+----'

这应该是你想要的。

答案 1 :(得分:0)

您应该可以在Talend Open Studio中完成。

我在这里附上一个带有JOB的图像,tJavaRow的内容和执行结果。 enter image description here

我离开了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库,它不会抛出异常但会返回一个默认值,我可以将其与要解析的值一起传递。