如何对变体列执行间接引用?
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;
我正在确定 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;