BigQuery 中的动态条件联接
Dynamic conditional joins in BigQuery
我正在尝试在 BigQuery 中编写一个动态条件语句,以根据特定条件动态加入 table。单个 ID 可以有 1 个或多个条件。
我如何动态 'filter' 一系列 ID 条件一起(使用 Table 1、2 和 3)以在我的最终 table 中获得一组 masterProductIds?
Table 1 - identification_table
Table 2 - filing_table
Table 3 - 价格
在这种情况下,对于 Id 1,我们有 3 个条件要评估,Id 2 有 2 个条件,Id 3 有 1 个条件。
在我们也有价格条件的情况下,它应该加入价格 table 并根据 table 中的运算符和值进行过滤 1. 至于产品条件,我不必加入任何 tables,我只采用 table 中的值 1.
我期望的最终结果集。
决赛Table
我目前所做的:
select masterProductId, row_number() over (partition by id ) sq
from `filing_table` p
left join `identification_table` pc
on case when subject = 'brand' then p.brandName when subject='category' then categoryName end = pc.boundaryValue
--on p.brandName = pc.boundaryValue or p.categoryName = boundaryValue
left join `price` pp
on p.code = pp.code
where 1=1
and pc.code = 'Id 2'
--and pp.RRP < safe_cast(pc1.boundaryValue as float64)
这将对所有内容进行整体评估。我不知道如何评估一组一组的 ID。
以下适用于 BigQuery Standard SQL 并假设表格设置如下(OP 在问题评论中同意)
identification_table
SELECT 'Id 1' id, 'masterProductId' subject, '=' operator, '1007' value UNION ALL
SELECT 'Id 1', 'brandName', '=', 'brand p' UNION ALL
SELECT 'Id 1', 'categoryName', '=', 'category 1' UNION ALL
SELECT 'Id 2', 'categoryName', '=', 'category 1' UNION ALL
SELECT 'Id 2', 'price', '<', '130' UNION ALL
SELECT 'Id 3', 'categoryName', '=', 'category 3'
filing_table
SELECT 11 code, 'category 1' categoryName, 'brand p' brandName, 1001 masterProductId UNION ALL
SELECT 22, 'category 1', 'brand z', 1002 UNION ALL
SELECT 33, 'category 2', 'brand c', 1003 UNION ALL
SELECT 44, 'category 2', 'brand v', 1004 UNION ALL
SELECT 55, 'category 3', 'brand e', 1005
price
SELECT 11 code, 3 price UNION ALL
SELECT 22, 100 UNION ALL
SELECT 33, 8 UNION ALL
SELECT 44, 9 UNION ALL
SELECT 77, 28
因此,下面从 filing_table
中摘录那些 masterProductId
符合 identification_table
的所有标准
EXECUTE IMMEDIATE '''
SELECT masterProductId
FROM (
SELECT f.*, price
FROM `filing_table` f
LEFT JOIN `price` p
USING(code)
)
WHERE ''' || (
SELECT STRING_AGG('(' || condition || ')', ' OR ')
FROM (
SELECT STRING_AGG(FORMAT('(%s %s %s)', subject, operator, value), ' AND ') condition
FROM `identification_table`,
UNNEST([IF(subject IN ('price', 'masterProductId'), value, '"' || value || '"')]) value
GROUP BY id
));
如果应用到答案顶部的示例数据 - 输出是
Row masterProductId
1 1001
2 1002
3 1005
我正在尝试在 BigQuery 中编写一个动态条件语句,以根据特定条件动态加入 table。单个 ID 可以有 1 个或多个条件。 我如何动态 'filter' 一系列 ID 条件一起(使用 Table 1、2 和 3)以在我的最终 table 中获得一组 masterProductIds?
Table 1 - identification_table
Table 2 - filing_table
Table 3 - 价格
在这种情况下,对于 Id 1,我们有 3 个条件要评估,Id 2 有 2 个条件,Id 3 有 1 个条件。
在我们也有价格条件的情况下,它应该加入价格 table 并根据 table 中的运算符和值进行过滤 1. 至于产品条件,我不必加入任何 tables,我只采用 table 中的值 1.
我期望的最终结果集。
决赛Table
我目前所做的:
select masterProductId, row_number() over (partition by id ) sq
from `filing_table` p
left join `identification_table` pc
on case when subject = 'brand' then p.brandName when subject='category' then categoryName end = pc.boundaryValue
--on p.brandName = pc.boundaryValue or p.categoryName = boundaryValue
left join `price` pp
on p.code = pp.code
where 1=1
and pc.code = 'Id 2'
--and pp.RRP < safe_cast(pc1.boundaryValue as float64)
这将对所有内容进行整体评估。我不知道如何评估一组一组的 ID。
以下适用于 BigQuery Standard SQL 并假设表格设置如下(OP 在问题评论中同意)
identification_table
SELECT 'Id 1' id, 'masterProductId' subject, '=' operator, '1007' value UNION ALL
SELECT 'Id 1', 'brandName', '=', 'brand p' UNION ALL
SELECT 'Id 1', 'categoryName', '=', 'category 1' UNION ALL
SELECT 'Id 2', 'categoryName', '=', 'category 1' UNION ALL
SELECT 'Id 2', 'price', '<', '130' UNION ALL
SELECT 'Id 3', 'categoryName', '=', 'category 3'
filing_table
SELECT 11 code, 'category 1' categoryName, 'brand p' brandName, 1001 masterProductId UNION ALL
SELECT 22, 'category 1', 'brand z', 1002 UNION ALL
SELECT 33, 'category 2', 'brand c', 1003 UNION ALL
SELECT 44, 'category 2', 'brand v', 1004 UNION ALL
SELECT 55, 'category 3', 'brand e', 1005
price
SELECT 11 code, 3 price UNION ALL
SELECT 22, 100 UNION ALL
SELECT 33, 8 UNION ALL
SELECT 44, 9 UNION ALL
SELECT 77, 28
因此,下面从 filing_table
中摘录那些 masterProductId
符合 identification_table
EXECUTE IMMEDIATE '''
SELECT masterProductId
FROM (
SELECT f.*, price
FROM `filing_table` f
LEFT JOIN `price` p
USING(code)
)
WHERE ''' || (
SELECT STRING_AGG('(' || condition || ')', ' OR ')
FROM (
SELECT STRING_AGG(FORMAT('(%s %s %s)', subject, operator, value), ' AND ') condition
FROM `identification_table`,
UNNEST([IF(subject IN ('price', 'masterProductId'), value, '"' || value || '"')]) value
GROUP BY id
));
如果应用到答案顶部的示例数据 - 输出是
Row masterProductId
1 1001
2 1002
3 1005