使用 Snowflake SQL 如何找到两条记录,然后根据这些记录将另一条记录更改为使用局部变量的预定义记录?
Using Snowflake SQL how do you find two records and then change another one based on those records to a predefined record using a local variable?
使用 SQL 如何使用两条记录找到一个位置,保留该位置并使用该记录将 'Nonsense' 值替换为保留位置的值?我将展示到目前为止我能写的东西,然后写出我仍在努力弄清楚的东西:
SELECT * FROM "TABLES". "ACCTS_OF_SUPERHEROS".;
DECLARE @count_rows INT = 0;
DECLARE @row_total INT = 0;
DECLARE @refAcctNum INT = 0;
DECLARE @selectedPlaceName TINYTEXT;
SET @row_total = SELECT COUNT (*)
WHILE countRows < row_total
for each acct_num store value in refAcctNum.
Using refAcctNum find place: "Gotham City", "Central City", "Metropolis", "Smallville", "Star City", "Fawcett City" store that in selectedPlaceName.
If refAccountNumber has Nonsense then replace with selectedPlaceName record
otherwise add + 1 to countRows and repeat.
END
当前table数据; “ACCTS_OF_SUPERHEROS”table:
| row | acct_num | exact_address | place
| --- | -------- |------------------|--------
| 1 | 049403 | 344 Clinton Str | Metropolis
| 2 | 049403 | 344 Clinton Str | Nonsense
| 3 | 049206 | 1007 Mountain Dr | Gotham City
| 4 | 049206 | 1007 Mountain Dr | Gotham City
| 5 | 049206 | 1096 Show Dr. | Fawcett City
| 6 | 049206 | 1096 Show Dr. | Nonsense
| 7 | 049206 | NULL | Nonsense
| 8 | 049291 | 1938 Sullivan Pl | Smallville
| 9 | 049293 | 700 Hamilton Str | Central City
| 10 | 049396 | 800 Nonsense Way | Nonsense
| 11 | 049396 | NULL | Nonsense
期望输出:
| row | acct_num | exact_address | place
| --- | -------- |------------------|--------
| 1 | 049403 | 344 Clinton Str | Metropolis
| 2 | 049403 | 344 Clinton Str | Metropolis
| 3 | 049206 | 1007 Mountain Dr | Gotham City
| 4 | 049206 | 1007 Mountain Dr | Gotham City
| 5 | 049206 | 1096 Show Dr. | Fawcett City
| 6 | 049206 | 1096 Show Dr. | Fawcett City
| 7 | 049206 | NULL | Fawcett City
| 8 | 049291 | 1938 Sullivan Pl | Smallville
| 9 | 049293 | 700 Hamilton Str | Central City
| 10 | 049396 | 800 Tidal Way | Star City
| 11 | 049396 | NULL | Star City
您可以使用 window 个函数:
select t.*,
max(case when place <> 'Nonsense' then place end) over (partition by acct_num) as imputed_place
from t;
这 returns NULL
如果给定 acct_num
的所有行都是 'Nonsense'
。您可以使用 COALESCE()
将值替换为其他值。
我正在阅读 Snowflake 中可用的 window 函数列表,认为您需要一个新的 window 函数。也许有人可以找到更内置的方法,但无论如何这里有一个用户定义的 table 函数 REPLACE_WITH_LKG 作为 window 函数实现,它将用最后一个已知的好值替换坏值。只要我打算写它,我认为它也可能是通用的,所以它使用正则表达式和 JavaScript RegExp 选项匹配“坏”值。
create or replace function REPLACE_WITH_LKG("VALUE" string, "REGEXP" string, "REGEXP_OPTIONS" string)
returns table(LKG_VALUE string)
language javascript
strict immutable
as
$$
{
initialize: function (argumentInfo, context) {
this.lkg = "";
},
processRow: function (row, rowWriter, context) {
const rx = new RegExp(row.REGEXP, row.REGEXP_OPTIONS);
if (!rx.test(row.VALUE)) {
this.lkg = row.VALUE;
}
rowWriter.writeRow({LKG_VALUE: this.lkg});
},
finalize: function (rowWriter, context) {},
}
$$;
select S.*, LKG.LKG_VALUE as PLACE
from superhero S, table(REPLACE_WITH_LKG(PLACE, 'Nonsense', 'ig')
over(partition by null order by "ROW")) LKG;
;
性能说明;数据显示的方式是除了整个 table 之外没有任何分区。那是因为一个明显的分区,按帐户的地方,不会工作。如果使用帐户,第 10 行从不同的 window 中获取其值,因此示例数据的显示方式需要是跨越整个 table 的 window。这不会很好地并行化,对于非常大的 tables 应该避免。
使用 SQL 如何使用两条记录找到一个位置,保留该位置并使用该记录将 'Nonsense' 值替换为保留位置的值?我将展示到目前为止我能写的东西,然后写出我仍在努力弄清楚的东西:
SELECT * FROM "TABLES". "ACCTS_OF_SUPERHEROS".;
DECLARE @count_rows INT = 0;
DECLARE @row_total INT = 0;
DECLARE @refAcctNum INT = 0;
DECLARE @selectedPlaceName TINYTEXT;
SET @row_total = SELECT COUNT (*)
WHILE countRows < row_total
for each acct_num store value in refAcctNum.
Using refAcctNum find place: "Gotham City", "Central City", "Metropolis", "Smallville", "Star City", "Fawcett City" store that in selectedPlaceName.
If refAccountNumber has Nonsense then replace with selectedPlaceName record
otherwise add + 1 to countRows and repeat.
END
当前table数据; “ACCTS_OF_SUPERHEROS”table:
| row | acct_num | exact_address | place
| --- | -------- |------------------|--------
| 1 | 049403 | 344 Clinton Str | Metropolis
| 2 | 049403 | 344 Clinton Str | Nonsense
| 3 | 049206 | 1007 Mountain Dr | Gotham City
| 4 | 049206 | 1007 Mountain Dr | Gotham City
| 5 | 049206 | 1096 Show Dr. | Fawcett City
| 6 | 049206 | 1096 Show Dr. | Nonsense
| 7 | 049206 | NULL | Nonsense
| 8 | 049291 | 1938 Sullivan Pl | Smallville
| 9 | 049293 | 700 Hamilton Str | Central City
| 10 | 049396 | 800 Nonsense Way | Nonsense
| 11 | 049396 | NULL | Nonsense
期望输出:
| row | acct_num | exact_address | place
| --- | -------- |------------------|--------
| 1 | 049403 | 344 Clinton Str | Metropolis
| 2 | 049403 | 344 Clinton Str | Metropolis
| 3 | 049206 | 1007 Mountain Dr | Gotham City
| 4 | 049206 | 1007 Mountain Dr | Gotham City
| 5 | 049206 | 1096 Show Dr. | Fawcett City
| 6 | 049206 | 1096 Show Dr. | Fawcett City
| 7 | 049206 | NULL | Fawcett City
| 8 | 049291 | 1938 Sullivan Pl | Smallville
| 9 | 049293 | 700 Hamilton Str | Central City
| 10 | 049396 | 800 Tidal Way | Star City
| 11 | 049396 | NULL | Star City
您可以使用 window 个函数:
select t.*,
max(case when place <> 'Nonsense' then place end) over (partition by acct_num) as imputed_place
from t;
这 returns NULL
如果给定 acct_num
的所有行都是 'Nonsense'
。您可以使用 COALESCE()
将值替换为其他值。
我正在阅读 Snowflake 中可用的 window 函数列表,认为您需要一个新的 window 函数。也许有人可以找到更内置的方法,但无论如何这里有一个用户定义的 table 函数 REPLACE_WITH_LKG 作为 window 函数实现,它将用最后一个已知的好值替换坏值。只要我打算写它,我认为它也可能是通用的,所以它使用正则表达式和 JavaScript RegExp 选项匹配“坏”值。
create or replace function REPLACE_WITH_LKG("VALUE" string, "REGEXP" string, "REGEXP_OPTIONS" string)
returns table(LKG_VALUE string)
language javascript
strict immutable
as
$$
{
initialize: function (argumentInfo, context) {
this.lkg = "";
},
processRow: function (row, rowWriter, context) {
const rx = new RegExp(row.REGEXP, row.REGEXP_OPTIONS);
if (!rx.test(row.VALUE)) {
this.lkg = row.VALUE;
}
rowWriter.writeRow({LKG_VALUE: this.lkg});
},
finalize: function (rowWriter, context) {},
}
$$;
select S.*, LKG.LKG_VALUE as PLACE
from superhero S, table(REPLACE_WITH_LKG(PLACE, 'Nonsense', 'ig')
over(partition by null order by "ROW")) LKG;
;
性能说明;数据显示的方式是除了整个 table 之外没有任何分区。那是因为一个明显的分区,按帐户的地方,不会工作。如果使用帐户,第 10 行从不同的 window 中获取其值,因此示例数据的显示方式需要是跨越整个 table 的 window。这不会很好地并行化,对于非常大的 tables 应该避免。