如何对变体列执行间接引用?

How to perform indirect references into a variant column?

我正在确定 structure/query 我需要处理变体列中的间接引用(即我想根据另一个 table 的定义为不同的行提取不同的字段)。

示例: 我有代表不同项目的变体数据,每个项目根据它们所属的类别具有完全不同的属性集。 虽然这些属性的名称因类别而异,但有一些共同的用途可以是 shared/identified.

所以我有一个 table(属性)定义每个 purpose/category 组合的 属性 名称

属性

| Category | Purpose | Property_Name | Property_Data_Type |
|----------|---------|---------------|--------------------|
|    car   |   name  |  model        |    string          |
|    car   |  brand  |  make         |    string          |
|    car   |  price  |  invoice      |    number          |
|  phone   |   name  |  product      |    string          |
|  phone   |  brand  |  manufacturer |    string          |
|  phone   |  price  |  msrp         |    number          |
|----------|---------|---------------|--------------------|

我有一个 table(商品),其中包含变体字段中每个商品的信息

项目

| Item_Id | Category | Properties                                                       |   
|---------|----------|------------------------------------------------------------------|
|     1   |   car    | {"make":"ford", "model":"focus", "invoice":18999}                |
|     2   |   car    | {"make":"audi", "model":"a5", "invoice":36487}                   |
|     3   | phone    | {"manufacturer":"apple", "product":"iphone 10", "msrp":679}      |
|     4   | phone    | {"manufacturer":"samsung", "product":"galaxy s20",  "msrp":1029} |
|---------|----------|------------------------------------------------------------------|

我想要做的是获取一个查询(或一个填充另一个 table 的过程),该查询将根据 [=35] 从 json 数据中提取值=] 定义的目的。 所以我会有一个可以给出以下结果的查询

| Item_Id | Category | Name       | Brand   | Price |
|---------|----------|------------|---------|-------|
|    1    |  car     | focus      | ford    | 18999 |
|    2    |  car     | a5         | audi    | 36487 |
|    3    |  phone   | iphone 10  | apple   |   679 |
|    4    |  phone   | galaxy s20 | samsung |  1029 |
|---------|----------|------------|---------|-------|

我很无聊所以写了这个。这是一个存储过程,将根据您上面的描述创建或替换名为 ITEM_VIEW 的视图。请注意,您的数据存在细微差异。 JSON 中 phone 的 属性 是 "model",但在 PROPERTIES table 中是 "manufacturer"。

任何时候更改属性 table,您都需要 运行 存储过程来重建视图。我把SQL语句和子句放到了模版里,大家可以根据需要修改。

如您在代码中所见,存储过程需要一个名为 PROPERTIES 的 table 和一个名为 ITEMS 的 table。如果您的实际 table 名称不同,您可以在找到它们的代码 and/or SQL 模板中更改它们。

create or replace procedure CREATE_ITEM_VIEW()
returns string
language javascript
as
$$

var nameClause = "";
var brandClause = "";
var priceClause = "";
var category, purpose, dataType, property;

var rs = GetResultSet("select * from PROPERTIES");

while (rs.next()){

    category = rs.getColumnValue("CATEGORY");
    purpose  = rs.getColumnValue("PURPOSE");
    property = rs.getColumnValue("PROPERTY_NAME");
    dataType = rs.getColumnValue("PROPERTY_DATA_TYPE");

    if (purpose == 'name'){
        nameClause += GetColumn(category, property, dataType) + "\n";
    }
    if (purpose == 'brand'){
        brandClause += GetColumn(category, property, dataType) + "\n";
    }
    if (purpose == 'price'){
        priceClause += GetColumn(category, property, dataType) + "\n";
    }
}

var viewSQL = GetViewSQL(nameClause, brandClause, priceClause);

return ExecuteSingleValueQuery("status", viewSQL);

// ----------------------End of Main Function ---------------------------------------

function GetColumn(category, name, dataType){
    var sql = "when '@~CATEGORY~@'    then PROPERTIES:@~NAME~@::@~NAME_DATA_TYPE~@";
    sql = sql.replace(/@~CATEGORY~@/g,       category);
    sql = sql.replace(/@~NAME~@/g,           name);
    sql = sql.replace(/@~NAME_DATA_TYPE~@/g, dataType);
    return sql;
}

function GetViewSQL(nameClause, brandClause, priceClause){

var sql = `
create or replace view ITEM_VIEW as
select  ITEM_ID,
        CATEGORY, 
        case CATEGORY

${nameClause}
        end as "NAME",
        case CATEGORY

${brandClause}
        end as BRAND,
        case CATEGORY

${priceClause}
        end as PRICE
from ITEMS;
`;
return sql;
}

function GetResultSet(sql){
    cmd1 = {sqlText: sql};
    stmt = snowflake.createStatement(cmd1);
    var rs;
    rs = stmt.execute();
    return rs;
}

function ExecuteSingleValueQuery(columnName, queryString) {
    var out;
    cmd1 = {sqlText: queryString};
    stmt = snowflake.createStatement(cmd1);
    var rs;

    rs = stmt.execute();
    rs.next();
    return rs.getColumnValue(columnName);
    return out;
}

$$;

创建存储过程后,运行它会像这样创建您的视图:

call create_item_view();

select * from ITEM_VIEW;