【问题标题】:How to implement `pivot` in clickhouse just like in dolphindb如何像在 dolphindb 中一样在 clickhouse 中实现 `pivot`
【发布时间】:2019-09-28 03:55:09
【问题描述】:

我想对一些数据做一些pivot 操作。就像跟随一样。

>>> df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two',
...                            'two'],
...                    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
...                    'baz': [1, 2, 3, 4, 5, 6],
...                    'zoo': ['x', 'y', 'z', 'q', 'w', 't']})
>>> df
    foo   bar  baz  zoo
0   one   A    1    x
1   one   B    2    y
2   one   C    3    z
3   two   A    4    q
4   two   B    5    w
5   two   C    6    t
>>> df.pivot(index='foo', columns='bar', values='baz')
bar  A   B   C
foo
one  1   2   3
two  4   5   6

我知道 DolphinDB 可以在 sql 中执行pivot

    dateValue=2007.08.01
    num=500
    syms = (exec count(*) from taq 
    where 
        date = dateValue, 
        time between 09:30:00 : 15:59:59, 
        0<bid, bid<ofr, ofr<bid*1.2
    group by symbol order by count desc).symbol[0:num]

    priceMatrix = exec avg(bid + ofr)/2.0 as price from taq 
    where 
        date = dateValue, Symbol in syms, 
        0<bid, bid<ofr, ofr<bid*1.2, 
        time between 09:30:00 : 15:59:59 
    pivot by time.minute() as minute, Symbol

但是如何在 clickhouse 中执行 pivot ?我应该使用客户端 API 来获取数据吗?但是行太多,处理太多行太难了。而如果我不能使用pandas,如何轻松实现pivot操作?

【问题讨论】:

    标签: database pivot clickhouse dolphindb


    【解决方案1】:

    这是可以帮助您开始的初步实施。

    备注:

    • 不支持行中的“孔”(每列应包含值)

    • 所有列的类型转换为通用类型(字符串)

    • 引入了字段 orderNum。它是结果中源列的顺序号(例如,'bar'-column 为 2nd)

    • 结果表示为具有 Array 类型的一列的行。数组项的顺序由 orderNum 定义。

    准备测试数据:

    CREATE TABLE test.pivot_test
    (    
        orderNum Int,
        s String,
        values Array(String)
    ) ENGINE = Memory;
    
    INSERT INTO test.pivot_test
    VALUES 
      (1, 'foo', ['one', 'one', 'one', 'two', 'two', 'two']),
      (3, 'baz', ['1', '2', '3', '4', '5', '6']),
      (4, 'zoo', ['x', 'y', 'z', 'q', 'w', 't']),
      (2, 'bar', ['A', 'B', 'C', 'A', 'B', 'C']);
    
    /* 
    The content of table test.pivot_test:
    
    ┌─orderNum─┬─s───┬─values────────────────────────────────┐
    │        1 │ foo │ ['one','one','one','two','two','two'] │
    │        3 │ baz │ ['1','2','3','4','5','6']             │
    │        4 │ zoo │ ['x','y','z','q','w','t']             │
    │        2 │ bar │ ['A','B','C','A','B','C']             │
    └──────────┴─────┴───────────────────────────────────────┘
    */
    

    枢轴仿真:

    SELECT arrayMap(x -> x.1, arraySort(x -> x.2, groupArray(value_ordernum))) as row
    FROM
    (
        SELECT
            (value, orderNum) AS value_ordernum,
            value_index
        FROM test.pivot_test
        ARRAY JOIN
            values AS value,
            arrayEnumerate(values) AS value_index
      /*
        The result of execution the nested query:
    
        ┌─value_ordernum─┬─value_index─┐
        │ ('one',1)      │           1 │
        │ ('one',1)      │           2 │
        │ ('one',1)      │           3 │
        │ ('two',1)      │           4 │
        │ ('two',1)      │           5 │
        │ ('two',1)      │           6 │
        │ ('1',3)        │           1 │
        │ ('2',3)        │           2 │
        │ ('3',3)        │           3 │
        │ ('4',3)        │           4 │
        │ ('5',3)        │           5 │
        │ ('6',3)        │           6 │
        │ ('x',4)        │           1 │
        │ ('y',4)        │           2 │
        │ ('z',4)        │           3 │
        │ ('q',4)        │           4 │
        │ ('w',4)        │           5 │
        │ ('t',4)        │           6 │
        │ ('A',2)        │           1 │
        │ ('B',2)        │           2 │
        │ ('C',2)        │           3 │
        │ ('A',2)        │           4 │
        │ ('B',2)        │           5 │
        │ ('C',2)        │           6 │
        └────────────────┴─────────────┘  
      */
    )
    GROUP BY value_index;
    
    /*
    The final result:
    
    ┌─row─────────────────┐
    │ ['two','A','4','q'] │
    │ ['one','C','3','z'] │
    │ ['one','B','2','y'] │
    │ ['two','B','5','w'] │
    │ ['one','A','1','x'] │
    │ ['two','C','6','t'] │
    └─────────────────────┘
    */
    

    【讨论】:

    • 如何使用普通表来实现。 foobarbazzoo 作为列而不是值
    • 无法使用 SQL 生成动态列,因此此处不按列拆分。据我了解,您将在服务器端处理此结果,因此处理具有数组类型的一列而不是几列不是问题。问题是如何识别数组中的项目 - 哪个是“bar”或“foo”?当 'foo'、'bar' 等列具有唯一 ID 时,它可以定义数组中项目的顺序(在这种情况下,示例中的列 'orderNum' 应替换为 ID)。
    猜你喜欢
    • 2014-11-15
    • 2015-12-20
    • 2020-02-26
    • 2022-12-11
    • 1970-01-01
    • 2019-06-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多