簡體   English   中英

雪花 - 產生嵌套的 JSON 輸出

[英]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.

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