【问题标题】:Concat each n rows in pentaho在pentaho中连接每n行
【发布时间】:2017-07-26 07:54:06
【问题描述】:

我正在尝试形成一个需要连接每 10 行值的转换。

第一步:表格输入(来自 Postgres DB 的查询:select id from tablename

上述查询的示例结果:

                  id
 00000191-555c-11e4-922d-29fb57a42e4c
 00000192-555c-11e4-922d-29fb57a42e4c
 00000193-555c-11e4-922d-29fb57a42e4c
 00000194-555c-11e4-922d-29fb57a42e4c
 00000195-555c-11e4-922d-29fb57a42e4c
 00000196-555c-11e4-922d-29fb57a42e4c
 00000197-555c-11e4-922d-29fb57a42e4c
 00000198-555c-11e4-922d-29fb57a42e4c
 00000199-555c-11e4-922d-29fb57a42e4c
 0000019a-555c-11e4-922d-29fb57a42e4c
 000001a3-3cf2-11e4-b398-e52ee0ec6a4c
 000002ad-3768-4242-88cf-96f27d0263af
 000003ea-26e3-11e4-ace7-15c7d609fa6e
 00000684-73fb-4d65-a502-87c4eb6607c1
 0000087a-f587-44fa-8e88-7bcae5bcb22c
 00000889-39c5-11e4-bd0e-c3f9d65ac856
 0000094c-be98-4456-8b49-6357a36581aa
 00000987-2f19-4574-ab85-6744a65ee4e3
 00000cd0-4097-11e4-a4e6-af71a3d902c0
 00000e1e-3b55-11e4-9897-d958d55e6784

在这里,我必须将每 10 行 id 连接成一行。例如。单行 1-10 行 id,另一行 11-20 行 id,依此类推。

预期输出:

ids

00000191-555c-11e4-922d-29fb57a42e4c,00000192-555c-11e4-922d-29fb57a42e4c,00000193-555c-11e4-922d-29fb57a42e4c,00000194-555c-11e4-922d-29fb57a42e4c,00000195-555c-11e4-922d-29fb57a42e4c,00000196-555c-11e4-922d-29fb57a42e4c,00000197-555c-11e4-922d-29fb57a42e4c,00000198-555c-11e4-922d-29fb57a42e4c,00000199-555c-11e4-922d-29fb57a42e4c,0000019a-555c-11e4-922d-29fb57a42e4c
000001a3-3cf2-11e4-b398-e52ee0ec6a4c,000002ad-3768-4242-88cf-96f27d0263af,000003ea-26e3-11e4-ace7-15c7d609fa6e,00000684-73fb-4d65-a502-87c4eb6607c1,0000087a-f587-44fa-8e88-7bcae5bcb22c,00000889-39c5-11e4-bd0e-c3f9d65ac856,0000094c-be98-4456-8b49-6357a36581aa,00000987-2f19-4574-ab85-6744a65ee4e3,00000cd0-4097-11e4-a4e6-af71a3d902c0,00000e1e-3b55-11e4-9897-d958d55e6784

我知道 Group By 或 Memory Group by 将连接行,但在这种情况下我可以使用它,如果可以,我该如何使用它。

请帮我解决这个问题。提前致谢!

【问题讨论】:

  • 编辑您的问题并提供示例数据和所需结果。
  • @GordonLinoff 添加了示例数据和预期输出。希望现在可以理解了。

标签: postgresql concatenation pentaho spoon pentaho-data-integration


【解决方案1】:

我认为解决方案是:

select string_agg(id, ',')
from (select t.*, row_number() over (order by id) - 1 as seqnum
      from t
     ) t
group by floor(seqnum / 10);

虽然这使用string_agg(),但我可能会使用数组作为结果。

【讨论】:

    【解决方案2】:

    如果您没有合适的字段来对您的 id 进行分组,请自己创建一个。

    在这种情况下,我会在查询中添加行号并将它们除以 10 以获得一个体面且易于配置的组。

    select row_number()/10 + 1 OVER (ORDER BY id) as rnum, id from tablename ORDER BY rnum
    

    这应该为您提供 10 行 rnum 1、10 行 rnum 2 等。将此字段配置为 Group By 字段,您就完成了。

    【讨论】:

    • 另外,您可以通过组合Add sequence 步骤然后在Calculator、UDJC、java 脚本步骤或 java 表达式中将计数器除以 10,在 PDI 中创建组字段。 PDI 方式比较笨拙,但如果您需要使用其他数据源,它可能会很有用。
    • 顺便说一句,您需要确保 Group By Step 的输入按组字段排序,以便获得正确的聚合。因此,您最好在上面的查询中包含 ORDER BY id 或 ORDER BY rnum。我不认为 PostgreSQL 在一般情况下为 row_number 值提供任何排序​​保证。
    • @user4637357 我会将其添加到答案中,但排序发生在窗口功能期间,因此应该没有必要。如果没有指定其他操作,优化器不会再次打乱记录。至少,我从未在其他 RDBMS 中看到过这种情况。
    【解决方案3】:

    像这样吗?

    t=# \x
    Expanded display is on.
    t=# with a as 
    (
      select ntile(2) over (order by id),id from tablename
    ) 
    select 
      string_agg(id,',') 
    from a 
    group by ntile;
    -[ RECORD 1 ]-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    string_agg | 00000191-555c-11e4-922d-29fb57a42e4c, 00000192-555c-11e4-922d-29fb57a42e4c, 00000193-555c-11e4-922d-29fb57a42e4c, 00000194-555c-11e4-922d-29fb57a42e4c, 00000195-555c-11e4-922d-29fb57a42e4c, 00000196-555c-11e4-922d-29fb57a42e4c, 00000197-555c-11e4-922d-29fb57a42e4c, 00000198-555c-11e4-922d-29fb57a42e4c, 00000199-555c-11e4-922d-29fb57a42e4c, 0000019a-555c-11e4-922d-29fb57a42e4c
    -[ RECORD 2 ]-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    string_agg |  000001a3-3cf2-11e4-b398-e52ee0ec6a4c, 000002ad-3768-4242-88cf-96f27d0263af, 000003ea-26e3-11e4-ace7-15c7d609fa6e, 00000684-73fb-4d65-a502-87c4eb6607c1, 0000087a-f587-44fa-8e88-7bcae5bcb22c, 00000889-39c5-11e4-bd0e-c3f9d65ac856, 0000094c-be98-4456-8b49-6357a36581aa, 00000987-2f19-4574-ab85-6744a65ee4e3, 00000cd0-4097-11e4-a4e6-af71a3d902c0, 00000e1e-3b55-11e4-9897-d958d55e6784
    

    【讨论】:

    • ntile(2) 不会根据数据集大小聚合不同数量的行吗?
    • 当然 - 我用 ntile(20/10) 作为你的例子
    • @VaoTsun 当表有数百万条记录时,上述查询的性能如何?
    • 伙计,如果您担心数百万行,您应该清楚地说明问题 - 而不是将 20 行分成两行。当然,内置的窗口函数将尽可能高效。
    • 对不起,我没有提到百万记录,我会试试这个。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-03-01
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多