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