如何旋转子组?

Posted

技术标签:

【中文标题】如何旋转子组?【英文标题】:How to pivot subgroups? 【发布时间】:2019-09-12 16:31:10 【问题描述】:

我们为 Clickhouse 创建了一个平面表,并试图从该表中获取记录以创建一个物化视图。逻辑是如果 e_id 为 null,则记录为“TypeB”,如果 e_id 不为 null,则记录为“TypeA”。 TypeA 和 TypeB 记录都将具有相同的 p_id 和 s_id。我们希望为每个 p_id+s_id 组合创建一条记录。

下面给出的查询适用于过滤器(p_id = 1 和 s_id = 1)但没有过滤器 - 例外是“DB::Exception:标量子查询返回多于一行” 是否可以在 ClickHouse 中执行此操作? 是否可以使用这样的查询创建物化视图?

select p_id,s_id,
       groupArray(e_id),
       groupArray(name),
       (select groupArray(name) 
           from flat_table
           where e_id is null and p_id =1 and s_id = 1
           group by p_id,s_id) as typeB
       from flat_table
       where e_id is not null and p_id =1 and s_id = 1
       group by p_id,s_id;
/*
This what the table looks like:
Flat_table
p_id  s_id  e_id  name
1     1      1     Jake
1     1      2     Bob
1     1      null  Barby
1     1      null  Ella

This is expected result:
p_id  s_id  e_id  typeA        typeB
1      1    [1,2] [Jake,Bob]   [Barby,Ella]
*/

【问题讨论】:

【参考方案1】:

让我们试试这个查询:

SELECT p_id, s_id, e_ids, typeA, typeB
FROM (
  SELECT
      p_id,
      s_id,
      groupArray((e_id, name)) eid_names,
      arrayMap(x -> x.1, arrayFilter(x -> not isNull(x.1), eid_names)) e_ids,
      arrayMap(x -> x.2, arrayFilter(x -> not isNull(x.1), eid_names)) typeA,
      arrayMap(x -> x.2, arrayFilter(x -> isNull(x.1), eid_names)) typeB
  FROM test.test_006
  GROUP BY p_id, s_id)
/* Result
┌─p_id─┬─s_id─┬─e_ids─┬─typeA────────────┬─typeB──────────────┐
│    2 │    2 │ [1,2] │ ['Jake2','Bob2'] │ ['Barby2','Ella2'] │
│    1 │    1 │ [1,2] │ ['Jake','Bob']   │ ['Barby','Ella']   │
└──────┴──────┴───────┴──────────────────┴────────────────────┘
*/

/* Data preparation queries */

CREATE TABLE test.test_006
(
    `p_id` Int32,
    `s_id` Int32,
    `e_id` Nullable(Int32),
    `name` String
)
ENGINE = Memory

INSERT INTO test.test_006
VALUES (1, 1, 1, 'Jake'), (1, 1, 2, 'Bob'), (1, 1, null, 'Barby'), (1, 1, null, 'Ella'),
  (2, 2, 1, 'Jake2'), (2, 2, 2, 'Bob2'), (2, 2, null, 'Barby2'), (2, 2, null, 'Ella2')

【讨论】:

像魅力一样工作!

以上是关于如何旋转子组?的主要内容,如果未能解决你的问题,请参考以下文章

如何获得 XMPP 子组?

如何对项目进行分组然后遍历子组[重复]

Grails springsecurity LDAP登录,如何按子组限制用户?

如何按子组收集数据?

如何将组合的 CSV 文件作为子组 /ds1 下的数据集导入?

如何在 s-s-rS 中创建一个子组,将其他组的特定行的值相加?