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

Sql 如何对变量列执行间接引用?,sql,snowflake-cloud-data-platform,variant,indirection,Sql,Snowflake Cloud Data Platform,Variant,Indirection,我正在确定将间接引用处理到变量列中所需的结构/查询(即,我希望根据另一个表的定义为不同的行提取不同的字段) 例如: 我有表示不同项目的变量数据,每个项目根据其所属的类别具有完全不同的属性集。 虽然这些属性的命名因类别而异,但有一些共同的用途可以共享/识别 因此,我有一个表(properties),它定义了每个用途/类别组合的属性名称 性质 | Category | Purpose | Property_Name | Property_Data_Type | |----------|-------

我正在确定将间接引用处理到变量列中所需的结构/查询(即,我希望根据另一个表的定义为不同的行提取不同的字段)

例如: 我有表示不同项目的变量数据,每个项目根据其所属的类别具有完全不同的属性集。 虽然这些属性的命名因类别而异,但有一些共同的用途可以共享/识别

因此,我有一个表(properties),它定义了每个用途/类别组合的属性名称

性质

| 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          |
|----------|---------|---------------|--------------------|
我有一个表(items),其中包含变量字段中每个项的信息

项目

我希望能够获得一个查询(或一个填充另一个表的过程),根据定义的属性目的从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表中是“manufacturer”

无论何时更改属性表,都需要运行存储过程来重建视图。我将SQL语句和子句放入模板中,以便您可以根据需要进行修改

正如您在代码中看到的,存储过程需要一个名为PROPERTIES的表和一个名为ITEMS的表。如果实际表名不同,可以在找到它们的代码和/或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;

您是否研究过使用Snowflake的存储过程?您将无法使用SQL实现这一点,但您可能已经在python中完成了类似的存储过程,因此我怀疑Javascript SP可以工作。挑战在于json字段是否具有层次结构。这会很快变得复杂,但也是可行的。我会看看这个。我已经编辑了原来的帖子以保持一致。我不认为是制造商/型号不一致,而是名称/型号的标签不正确。谢谢,有道理。。。如果你有任何问题,让它工作,让我知道。好的-这肯定是我的工作。但是我有一个问题,那就是你为Get\u\u列逻辑创建了三个不同的函数是否有特殊的原因?在我看来,你可以推广这一点,只需使用一个函数就可以了。你的观点很好。在编写过程中,我重构了一些代码,但没有意识到Get\uuuu列的内容是一样的。我更新了示例并切换到标准JavaScript替换标记${variableName},它们在那里工作。有时,当被特殊字符包围时,它们似乎不起作用,所以我把替换标记留在了那里。
call create_item_view();

select * from ITEM_VIEW;