簡體   English   中英

將Clickhouse數組返回為列

[英]Return clickhouse array as column

Clickhouse是否有可能將包含一對數組的結果轉換為列?

形成此結果:

┌─f1──┬f2───────┬f3─────────────┐
│ 'a' │ [1,2,3] │ ['x','y','z'] │
│ 'b' │ [4,5,6] │ ['x','y','z'] │
└─────┴─────────┴───────────────┘

至 :

┌─f1──┬x──┬y──┬z──┐
│ 'a' │ 1 │ 2 │ 3 │
│ 'b' │ 4 │ 5 │ 6 │
└─────┴───┴───┴───┘

想法是不必重復每一行的標題值。

在我的情況下,“標頭”數組f3通過查詢唯一並連接到f1,f2。

您可以借助indexOf函數來實現。

SELECT *
FROM test_sof 

┌─f1─┬─f2──────┬─f3────────────┐
│ a  │ [1,2,3] │ ['x','y','z'] │
└────┴─────────┴───────────────┘
┌─f1─┬─f2────────┬─f3────────────────┐
│ c  │ [7,8,9,0] │ ['x','y','z','n'] │
└────┴───────────┴───────────────────┘
┌─f1─┬─f2─────────┬─f3────────────────┐
│ d  │ [7,8,9,11] │ ['x','y','z','n'] │
└────┴────────────┴───────────────────┘
┌─f1─┬─f2──────┬─f3────────────┐
│ b  │ [4,5,6] │ ['x','y','z'] │
└────┴─────────┴───────────────┘

4 rows in set. Elapsed: 0.001 sec.

然后:

SELECT 
    f1, 
    f2[indexOf(f3, 'x')] AS x, 
    f2[indexOf(f3, 'y')] AS y, 
    f2[indexOf(f3, 'z')] AS z, 
    f2[indexOf(f3, 'n')] AS n
FROM test_sof 
ORDER BY 
    f1 ASC, 
    x ASC

┌─f1─┬─x─┬─y─┬─z─┬──n─┐
│ a  │ 1 │ 2 │ 3 │  0 │
│ b  │ 4 │ 5 │ 6 │  0 │
│ c  │ 7 │ 8 │ 9 │  0 │
│ d  │ 7 │ 8 │ 9 │ 11 │
└────┴───┴───┴───┴────┘

4 rows in set. Elapsed: 0.002 sec. 

請記住以下情況:數據頭數組中不存在標頭數組的索引,反之亦然。

UPD :如何在不知道“標頭”的情況下獲取數據的方式。

您將獲得三列,第三列帶有標題。

SELECT 
    f1, 
    f2[num] AS f2_el, 
    f3[num] AS f3_el
FROM test_sof 
ARRAY JOIN arrayEnumerate(f2) AS num
ORDER BY f1 ASC

┌─f1─┬─f2_el─┬─f3_el─┐
│ a  │     1 │ x     │
│ a  │     2 │ y     │
│ a  │     3 │ z     │
│ b  │     4 │ x     │
│ b  │     5 │ y     │
│ b  │     6 │ z     │
│ c  │     7 │ x     │
│ c  │     8 │ y     │
│ c  │     9 │ z     │
│ c  │     0 │ n     │
│ d  │     7 │ x     │
│ d  │     8 │ y     │
│ d  │     9 │ z     │
│ d  │    11 │ n     │
└────┴───────┴───────┘

14 rows in set. Elapsed: 0.006 sec.

這是一個有趣的難題。 正如已經指出的那樣,indexOf()函數似乎是在ClickHouse中旋轉數組列的最佳方法,但需要顯式選擇數組位置。 如果您使用的是Python,而結果集不是那么大,則可以通過將數組值翻轉到SQL中的行,然后在Python中旋轉f2和f3列,以更一般的方式解決問題。 運作方式如下。

首先,使用clickHouse-sqlalchemy和pandas將匹配的數組擴展為以下行。 (此示例使用在Anaconda上運行的Jupyter Notebook。)

# Load SQL Alchemy and connect to ClickHouse
from sqlalchemy import create_engine
%load_ext sql
%sql clickhouse://default:@localhost/default

# Use JOIN ARRAY to flip corresponding positions in f2, f3 to rows.
result = %sql select * from f array join f2, f3
df = result.DataFrame()
print(df)

數據框如下所示:

  f1  f2 f3
0  a   1  x
1  a   2  y
2  a   3  z
3  b   4  x
4  b   5  y
5  b   6  z

現在我們可以將f2和f3轉換為新的數據幀。

dfp = df.pivot(columns='f3', values='f2', index='f1')
print(dfp)

新的數據幀dfp如下所示:

f3  x  y  z
f1         
a   1  2  3
b   4  5  6

此解決方案要求您在數據庫外部工作,但具有的優點是,只要名稱和值匹配,它通常就可用於任何一組數組。 例如,如果我們添加另一行具有不同的值和屬性,則相同的代碼將獲得正確的答案。 這是新的一行。

insert into f values ('c', [7,8,9,10], ['x', 'y', 'aa', 'bb'])

數據透視圖框將顯示如下。 NaN對應於缺失值。

f3   aa    bb    x    y    z
f1                          
a   NaN   NaN  1.0  2.0  3.0
b   NaN   NaN  4.0  5.0  6.0
c   9.0  10.0  7.0  8.0  NaN

有關此解決方案的更多信息,請參見https://pandas.pydata.org/pandas-docs/stable/getting_started/dsintro.htmlhttps://github.com/xzkostyan/clickhouse-sqlalchemy

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM