Sql 如何在DBT中选择bigquery表的最新分区而不扫描整个表?
为了节省查询成本,我尝试从BigQuery表中选择最新的分区,而不扫描DBT模型中的整个表 DBT不允许在数据模型中使用分号,因此使用Sql 如何在DBT中选择bigquery表的最新分区而不扫描整个表?,sql,google-bigquery,dbt,Sql,Google Bigquery,Dbt,为了节省查询成本,我尝试从BigQuery表中选择最新的分区,而不扫描DBT模型中的整个表 DBT不允许在数据模型中使用分号,因此使用DECLARE+SET脚本语句无法按建议工作 DBT有一个sql_头宏,允许在头中设置一些变量,但该头不接受对数据模型的引用,或者至少没有编译以下代码: {{ config( sql_header=" DECLARE latest_partition_date DATE; DECLARE latest_load_timestamp TIMEST
DECLARE
+SET
脚本语句无法按建议工作
DBT有一个sql_头宏,允许在头中设置一些变量,但该头不接受对数据模型的引用,或者至少没有编译以下代码:
{{ config(
sql_header=" DECLARE latest_partition_date DATE;
DECLARE latest_load_timestamp TIMESTAMP;
SET latest_partition_date = (SELECT MAX(_PARTITIONDATE) FROM {{ ref("model") }} );
SET latest_load_timestamp = (SELECT MAX(loaded_at) FROM {{ ref("model") }} WHERE _PARTITIONDATE = latest_partition_date);"
) }}
-- set the main query
SELECT * FROM {{ ref("model") }}
WHERE
-- Select the latest partition to reduce 'Bytes processed' for loading the query.
_PARTITIONDATE = latest_partition_date
-- Select the latest load within the latest partition to get only one duplicate of data.
AND loaded_at = latest_load_timestamp
我需要用标准SQL解决这个问题
其他建议的方法包括设置
,其中_PARTITIONDATE=CURRENT_DATE()
或使用DATE\u SUB(CURRENT_DATE(),3)
,但这些方法并不满足要求,因为数据加载中断是不可预测的,只有动态选择最新的才会起作用。这可能吗?您可以在另一个查询中执行此操作,并将结果作为一个变量,如下所示:
{%- call statement('max_partition', fetch_result=True) -%}
SELECT MAX(_PARTITIONDATE) FROM {{ ref("model") }} )
{%- endcall -%}
{%- set max_date = load_result('max_partition')['data'][0][0] -%}
SELECT * FROM {{ ref("model") }}
WHERE
_PARTITIONDATE = {{ max_date }}
因为最初的问题是关于日期的,所以缺少正确的数据类型转换 最后,我认为转换到正确的数据类型需要在jinja中完成,而不是使用SQL,以便查询接受正确的变量。另外,
{{max_date}}
需要引号
我找到的最终解决方案是:
{%- call statement('max_partition_date_query', True) -%}
SELECT MAX(_PARTITIONDATE) as max_partition_date FROM {{ ref('model') }}
{%- endcall -%}
{%- set max_timestamp = load_result('max_partition_date_query')['data'][0][0] -%}
{%- set max_date = max_timestamp.strftime('%Y-%m-%d') -%}
select * FROM {{ ref('model') }}
WHERE _PARTITIONDATE = '{{ max_date }}'
当我运行此命令时,会收到错误消息:
运算符没有匹配的签名=参数类型:DATE,INT64。支持的签名:ANY=ANY
。这可能是因为\u PARTITIONDATE
的类型是DATE
,但它的计算结果似乎是and INT。您知道如何解决这个问题吗?那么您可能需要强制转换它,以便从{ref(“model”)}中选择强制转换(日期(MAX(\u PARTITIONDATE))作为字符串)来检索值,也许您需要再次强制转换它,以便在主查询中使用它。我有一个使用时间戳
列的类似示例,但我没有尝试使用\u PARTITIONDATE
我尝试强制转换,但在编译时bgiquery忽略了这一点,仍然继续强制变量为整数。我得到的解决方案需要在jinja内进行转换