Как выполнить косвенные ссылки в столбце вариантов? - PullRequest
0 голосов
/ 28 апреля 2020

Я определяю структуру / запрос, который мне понадобится обрабатывать косвенными ссылками в столбце варианта (т.е. я хочу извлечь разные поля для разных строк на основе определений другой таблицы).

Пример: У меня есть варианты данных, которые представляют разные элементы, каждый из которых имеет совершенно разные наборы свойств в зависимости от категории, к которой они принадлежат. Хотя эти свойства называются по-разному в зависимости от категории, есть некоторые общие цели, которые можно разделить / идентифицировать.

Поэтому у меня есть таблица (свойства), которая определяет имя свойства для каждой комбинации цели / категории

Свойства

| 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          |
|----------|---------|---------------|--------------------|

и у меня есть таблица (элементы), которая содержит информацию для каждого элемента в поле варианта

Элементы

| 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} |
|---------|----------|------------------------------------------------------------------|

Что Я хочу иметь возможность получить запрос (или процесс для заполнения другой таблицы), который извлекал бы значения из данных 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 |
|---------|----------|------------|---------|-------|

1 Ответ

1 голос
/ 29 апреля 2020

Мне было скучно, поэтому я написал это. Это хранимая процедура, которая создаст или заменит представление ITEM_VIEW в соответствии с вашим описанием выше. Обратите внимание, что в ваших данных есть небольшое несоответствие. Свойство для телефона в JSON - «модель», но в таблице «СВОЙСТВА» - «производитель».

Каждый раз, когда вы изменяете таблицу PROPERTIES, вам необходимо запустить хранимую процедуру, чтобы перестроить представление. Я поместил оператор 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;
...