BigQuery JavaScript UDF 使用 SQL 查询中的值调用数组
Posted
技术标签:
【中文标题】BigQuery JavaScript UDF 使用 SQL 查询中的值调用数组【英文标题】:BigQuery JavaScript UDF to call Array with values from SQL query 【发布时间】:2021-05-30 02:45:58 【问题描述】:我正在尝试编写我的第一个 Bigquery UDF 函数(转换 Oracle 函数),感谢 SO 的帮助,到目前为止我能够编写部分代码,如下所示,
我的任务是,当我们传递了诸如 admission_date、input1、input2 之类的参数时,应该根据少数计算(而不是周末或节假日)来计算出院日期。
对任何错误或任何麻烦表示歉意
这是我的代码:
DECLARE list ARRAY <STRING>;
DECLARE v_holiday STRING DEFAULT 'No';
DECLARE v_due_report INT64;
DECLARE v_due_report_cnt INT64;
DECLARE v_days INT64;
DECLARE p_date DATE;
DECLARE p_input1 STRING;
DECLARE p_input2 STRING;
DECLARE v_bus_day STRING;
DECLARE v_cnt INT64 DEFAULT 1;
DECLARE v_max_days INT64 DEFAULT 1;
#SET v_holiday = (SELECT CASE WHEN EXISTS (SELECT 1 FROM `examples.date_calendar` WHERE HOLIDAY = DATE(p_date)) THEN 'Yes' ELSE 'No' END);
select ARRAY(SELECT holiday from `examples.date_calendar`) AS list;
SET v_due_report_cnt = (SELECT COUNT(*) FROM `examples.report_assessments` WHERE p_date BETWEEN START_DATE AND END_DATE
AND p_input1 = ICD_9_CLASS AND p_input2 = LAST_MEDICATION);
CREATE TEMP FUNCTION patient_report_date(p_admit_date DATE, p_input1 STRING,p_input2 STRING)
RETURNS STRING
LANGUAGE js AS """
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var dayName = days[p_admit_date.getDay()];
if(p_admit_date < Date.parse("2016-02-01")
v_bus_day = p_admit_date.setDate(date.getDate() + 2);
return v_bus_day;
# SET v_HOLIDAY = (SELECT CASE WHEN EXISTS (SELECT 1 FROM `examples.date_calendar` WHERE HOLIDAY = TRUNC(p_admit_date)) THEN 'Yes' ELSE 'No' END)
if(!(dayName) in ('Saturday', 'Sunday')) && (v_holiday == 'No')
v_days = 2;
else
v_days = 3;
p_date_trunc_time = new Date(p_date.getFullYear(), p_date.getMonth(), p_date.getDate());
v_bus_day = new Date(p_date_trunc_time.setSeconds(p_date_trunc_time.getSeconds() + 1));
if(p_admit_date < Date.parse("2020-07-01")
v_due_report = 0
#SET v_due_report_cnt = (SELECT COUNT(*) FROM `examples.report_assessments` WHERE p_admit_date BETWEEN START_DATE AND END_DATE
#AND p_input1 = ICD_9_CLASS AND p_input2 = LAST_MEDICATION);
else if (v_due_report_cnt > 0)
v_due_report = 4
v_days = v_days + v_due_report;
while max_days <= v_days
if (! days[(p_admit_date + day).getDay()] in ('Saturday','Sunday') && (list.indexOf(p_admit_date)==-1)
v_cnt++
max_days++
day++
v_bus_day = p_admit_date + v_vcnt;
return v_bus_day
""";
WITH data_date AS (
SELECT DATE("2021-05-31") AS p_DATE, "ICD8081" AS p_input1, "CDE2" AS p_input2 UNION ALL
SELECT DATE("2021-05-30"),"ICD8211","DER2"
)
SELECT p_DATE,
p_input1,
p_input2,
patient_report_date(p_DATE,p_input1,p_input2) discharge_date
FROM data_date;
当我执行该函数时,它向我抛出了错误“SyntaxError: Unexpected Token” 对此代码的任何建议或反馈都会有所帮助。 感谢您的帮助 感谢您阅读我的帖子。
更新的代码:最后,我能够让我的代码正常工作,我想添加 SO,所以它可能对某人有用。
DECLARE holiday_list ARRAY <STRING>;
DECLARE holiday_weekend ARRAY <STRING>;
DECLARE report_assessments ARRAY <STRUCT<ICD_9_CLASS STRING,LAST_MEDICATION STRING>>;
DECLARE p_admit_date DATE;
DECLARE p_input1 STRING;
DECLARE p_input2 STRING;
SET holiday_list = (SELECT ARRAY(SELECT CAST(holiday AS STRING) FROM `examples.date_calendar`));
SET v_due_report = (SELECT ARRAY(SELECT STRUCT(CAST(ICD_9_CLASS AS STRING) AS ICD_9_CLASS, CAST(LAST_MEDICATION AS STRING) AS LAST_MEDICATION) FROM `examples.report_assessments`));
CREATE TEMP FUNCTION patient_report_date(p_admit_date DATE, p_input1 STRING,p_input2 STRING)
RETURNS STRING
LANGUAGE js AS """
var days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var holiday_weekend = ['Saturday','Sunday'];
var v_signature=0;
var v_days=0;
var v_day =1;
var v_cnt=0;
var v_max_days=1;
if(p_admit_date < new Date("2016-02-01"))
p_admit_date.setDate(p_admit_date.getDate() + 2);
else
if((holiday_weekend.indexOf(days[p_admit_date.getDay()]) === -1) && (holiday_list.indexOf(p_admit_date) === -1))
v_days = 2;
else
v_days = 3;
for(var i = 0; i < report_assessments.length; i++)
if ((report_assessments[i]['ICD_9_CLASS'] === p_input1) && (signature_assessments[i]['LAST_MEDICATION'] === p_input2))
v_signature++;
if (p_admit_date < Date("2020-07-01") && (v_signature === 0))
v_days = v_days;
else if (v_signature > 0)
v_days = v_days + 4;
function addDays(date, days)
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
while max_days <= v_days
if ((holiday_list.indexOf(addDays(p_admit_date,v_day).toISOString().slice(0, 10)) === -1) && (holiday_weekend.indexOf(days[addDays(p_admit_date,v_day).getUTCDay()]) === -1))
v_max_days++;
v_day++;
v_cnt++;
p_admit_date.setDate(p_admit_date.getDate() + v_cnt);
return p_admit_date;
""";
WITH data_date AS (
SELECT DATE("2021-05-31") AS p_DATE, "ICD8081" AS p_input1, "CDE2" AS p_input2,holiday_list, report_assessments UNION ALL
SELECT DATE("2021-05-30"),"ICD8211","DER2",holiday_list, report_assessments
)
SELECT p_DATE,
p_input1,
p_input2,
patient_report_date(p_DATE,p_input1,p_input2,holiday_list, report_assessments) discharge_date
FROM `examples.tabledata`; ```
【问题讨论】:
【参考方案1】:是的,javascript UDF 是 also persistent。只需删除 TEMP
并选择指定项目名称和数据集名称:
CREATE FUNCTION project_name.dataset_name.patient_report_date(...)
【讨论】:
谢谢@Sergey,我想将值从上面的数组传递到UDF JavaScript UDF 也可以接收数组 - cloud.google.com/bigquery/docs/reference/standard-sql/… 示例 - ***.com/questions/65738242/… 非常感谢 Sergey,我可以使用list.indexOf(p_admit_date)==-1
来检查上面声明的数组中是否存在日期
我已经用示例选择语句更新了代码,当我在 BigQuery 中执行时它失败并且不知道如何调试,你能帮我解决这个问题以上是关于BigQuery JavaScript UDF 使用 SQL 查询中的值调用数组的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery JavaScript UDF:V8 实例的区域
用于合并值列表/数组的 BigQuery JavaScript UDF
描述如何在 SQL 中内联定义 Javascript UDF 函数的 BigQuery 文档在哪里(不是在 UDF 编辑器或单独的文件中)?
使用 JavaScript BigQuery UDF 解密/解码 AES256 [重复]