[英]Snowflake - produce nested JSON ouput
我已經為此苦苦掙扎了很長時間。 我有下表...
郵政編碼 | 家庭 | 懷特電纜 | 懷特電纜最快下降 | B4RN | B4RN 降速最快 |
---|---|---|---|---|---|
X24 888 | 34 | 1 | 108.2 | 0 | 0 |
BT36 7JU | 17 | 0 | 0 | 1 | 274.23 |
我想要做的是輸出 JSON 如下(這里是一行)
{'postcode':"X24 888",
'households':34,
'providers':[{'name':"wight cable",
'fastest_down':108.2,
'present':1},
{'name':"B4RN",
'fastest_down':0,
'present':0}']
}
實際上有大約 50 列這樣的列。 我可以使用SHOW COLUMNS LIKE '%fastest down%' IN TABLE TABLE1
類的命令獲取列表,但我正在努力循環遍歷表以捕獲這些數據以及特定的嵌套 json 結構。
這是我到目前為止所得到的。 也許此時只需進行一些小的編輯即可獲得我需要的內容。
create or replace function custom_object_assign(o1 VARIANT, o2 VARIANT)
returns VARIANT
language javascript
as 'return Object.assign(O1, O2);';
with t1 AS
(
SELECT OBJECT_CONSTRUCT(
'_id', h."ID",
'providers', array_agg(object_construct(
'wight cable', h."wight cable",
'wight cable fastest down', h."wight cable fastest down")
)) AS dc
FROM TABLE1 h
group by "ID"
),
t2 AS
(SELECT OBJECT_CONSTRUCT(
'_id', h."ID",
'rmpostcode', "rmpostcode"
) AS rs
FROM TABLE1 h
)
SELECT custom_object_assign(dc, rs)
FROM t1
JOIN t2
ON rs:"_id" = dc:"_id"
LIMIT 10;
這是返回的東西,如
{ "_id": "786516", "providers": [ { "wight cable": 0 } ], "rmpostcode": "LL65 1SJ" }
還不是我需要的!
這是一個使用存儲過程讀取源表並將行添加到目標表的示例。 您可以在代碼中看到有用於定義源表和目標表的常量。
限制:目前,代碼期望郵政編碼、家庭和隨后的“財產”+“財產最快下降”列處於有序的序數 position 中。 如果不是這種情況,則需要有一個循環來讀取列名以查找這些列在序號位置的位置。
使用說明:JavaScript 正在構建自定義 JSON。 由於 Snowflake 不喜歡單行插入,因此它正在構造一個 JSON 數組並展平該數組以一次插入 1000 行。 有一個設置行緩沖區的常量。 如果 JSON 超過 16MB,它將失敗,因此如果發生這種情況,可能需要向下調整。
建議:如果你想生產它,你可能想從你的源表中創建一個 stream 表。 這將使使用此 SP 僅處理新行變得更加容易。 https://snowflake.pavlik.us/index.php/2020/01/12/snowflake-streams-made-simple 。 需要修改代碼以忽略最后三個元數據列,然后運行 DML(從 1 = 0 的 stream_table 插入 target_table)以推進 stream。
這是填寫目標表以開始使用的 SP 代碼。
create or replace table FLAT_VALUES
(
"postcode" string
,"households" int
,"wight cable" int
,"wight cable fastest down" float
,"B4RN" int
,"B4RN fastest down" float
)
;
insert into FLAT_VALUES select 'X24 888', 34, 1, 108.2, 0, 0;
insert into FLAT_VALUES select 'BT36 7JU', 17, 0, 0, 1, 274.23;
create or replace table NESTED_JSON(v variant);
create or replace procedure GET_NESTED_JSON()
returns variant
language javascript
as
$$
var out = {};
const INPUT_TABLE = "FLAT_VALUES";
const OUTPUT_TABLE = "NESTED_JSON";
const INSERT_BUFFER_ROWS = 1000;
class Query{
constructor(statement){
this.statement = statement;
}
}
var selectSQL = `select * from ${INPUT_TABLE}`;
var json = [];
var row = {};
var colArr = [];
var subRow = {};
var rowBuffer = 0;
var rowsInserted = 0;
var selectQuery = getQuery(selectSQL);
while (selectQuery.resultSet.next()) {
row = {};
rowBuffer++;
row[selectQuery.statement.getColumnName(1)] = selectQuery.resultSet.getColumnValue(1);
row[selectQuery.statement.getColumnName(2)] = selectQuery.resultSet.getColumnValue(2);
colArr = [];
for(col = 3; col <= selectQuery.statement.getColumnCount(); col = col + 2) {
subRow = {};
subRow["name"] = selectQuery.statement.getColumnName(col);
subRow["fastest_down"] = selectQuery.resultSet.getColumnValue(selectQuery.statement.getColumnName(col) + " fastest down");
subRow["present"] = selectQuery.resultSet.getColumnValue(selectQuery.statement.getColumnName(col));
colArr.push(subRow);
}
row["providers"] = colArr;
json.push(row);
if (rowBuffer == INSERT_BUFFER_ROWS) {
rowBuffer = 0;
insertRows(OUTPUT_TABLE, json);
rowsInserted += rowBuffer;
}
}
if (rowBuffer > 0) {
insertRows(OUTPUT_TABLE, json);
rowsInserted += rowBuffer;
}
out["ROWS_INSERTED"] = rowsInserted;
return out;
function insertRows(targetTable, json) {
var jsonString = JSON.stringify(json);
var insertSQL = `insert into NESTED_JSON select VALUE from table(flatten(parse_json('${jsonString}')))`;
var insertQuery = getQuery(insertSQL);
}
function getQuery(sql){
var cmd = {sqlText: sql};
var query = new Query(snowflake.createStatement(cmd));
try {
query.resultSet = query.statement.execute();
} catch (e) {
query.error = e.message;
}
return query;
}
$$;
call get_nested_json();
select * from NESTED_JSON;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.