Sql 如何从BigQuery表中获取相应的列,这些列的值与连接的另一个表列的值相匹配?

Sql 如何从BigQuery表中获取相应的列,这些列的值与连接的另一个表列的值相匹配?,sql,join,google-bigquery,case,Sql,Join,Google Bigquery,Case,场景: 有两个BigQuery表A和B,有多列和公共键列。需要使用公共键列连接两个表,并从另一个表中获取相应的值,如下面的示例所述 输入: 我有两张桌子 表A: store category city 11 aaa xx 12 bbb yy 12 ccc zz 13 ddd xy store sale1 sale2 sale3 11 0.5 0.75

场景: 有两个BigQuery表A和B,有多列和公共键列。需要使用公共键列连接两个表,并从另一个表中获取相应的值,如下面的示例所述

输入: 我有两张桌子

表A:

store   category    city
11      aaa         xx
12      bbb         yy
12      ccc         zz
13      ddd         xy
store   sale1   sale2   sale3
11      0.5     0.75    0.25
12      1.2     1.25    1.23
13      0.9     0.87    0.54
store   category    city    sale
11      aaa         xx      0.5
12      bbb         yy      1.25
12      ccc         zz      1.23
13      ddd         xy      0.87
with res as 
    (select 
    a.store,
    a.category,
    a.city
    )
SELECT store, category, city,   
    case
        when category in ('aaa') then sale=b.sale1
        when category in ('bbb','ddd') then sale=b.sale2
        when category in ('ccc') then sale=b.sale3
    end
    as sale
FROM `tableA` AS a
JOIN `tableB` AS b
ON a.store = CAST(b.store AS STRING)
表B:

store   category    city
11      aaa         xx
12      bbb         yy
12      ccc         zz
13      ddd         xy
store   sale1   sale2   sale3
11      0.5     0.75    0.25
12      1.2     1.25    1.23
13      0.9     0.87    0.54
store   category    city    sale
11      aaa         xx      0.5
12      bbb         yy      1.25
12      ccc         zz      1.23
13      ddd         xy      0.87
with res as 
    (select 
    a.store,
    a.category,
    a.city
    )
SELECT store, category, city,   
    case
        when category in ('aaa') then sale=b.sale1
        when category in ('bbb','ddd') then sale=b.sale2
        when category in ('ccc') then sale=b.sale3
    end
    as sale
FROM `tableA` AS a
JOIN `tableB` AS b
ON a.store = CAST(b.store AS STRING)
预期输出-结果表C:

store   category    city
11      aaa         xx
12      bbb         yy
12      ccc         zz
13      ddd         xy
store   sale1   sale2   sale3
11      0.5     0.75    0.25
12      1.2     1.25    1.23
13      0.9     0.87    0.54
store   category    city    sale
11      aaa         xx      0.5
12      bbb         yy      1.25
12      ccc         zz      1.23
13      ddd         xy      0.87
with res as 
    (select 
    a.store,
    a.category,
    a.city
    )
SELECT store, category, city,   
    case
        when category in ('aaa') then sale=b.sale1
        when category in ('bbb','ddd') then sale=b.sale2
        when category in ('ccc') then sale=b.sale3
    end
    as sale
FROM `tableA` AS a
JOIN `tableB` AS b
ON a.store = CAST(b.store AS STRING)
解释的输出:

store   category    city
11      aaa         xx
12      bbb         yy
12      ccc         zz
13      ddd         xy
store   sale1   sale2   sale3
11      0.5     0.75    0.25
12      1.2     1.25    1.23
13      0.9     0.87    0.54
store   category    city    sale
11      aaa         xx      0.5
12      bbb         yy      1.25
12      ccc         zz      1.23
13      ddd         xy      0.87
with res as 
    (select 
    a.store,
    a.category,
    a.city
    )
SELECT store, category, city,   
    case
        when category in ('aaa') then sale=b.sale1
        when category in ('bbb','ddd') then sale=b.sale2
        when category in ('ccc') then sale=b.sale3
    end
    as sale
FROM `tableA` AS a
JOIN `tableB` AS b
ON a.store = CAST(b.store AS STRING)
第1点:使用公共列“store”连接两个表

第2点:检查列类别是否='aaa',然后从表B中获取列'sale1',如果类别在('bbb','ddd')中,则获取列'sale2',如果类别='ccc',则获取列'sale3',并将相应的值作为列'sale'存储在结果表C中

尝试了BIGQUERY:

store   category    city
11      aaa         xx
12      bbb         yy
12      ccc         zz
13      ddd         xy
store   sale1   sale2   sale3
11      0.5     0.75    0.25
12      1.2     1.25    1.23
13      0.9     0.87    0.54
store   category    city    sale
11      aaa         xx      0.5
12      bbb         yy      1.25
12      ccc         zz      1.23
13      ddd         xy      0.87
with res as 
    (select 
    a.store,
    a.category,
    a.city
    )
SELECT store, category, city,   
    case
        when category in ('aaa') then sale=b.sale1
        when category in ('bbb','ddd') then sale=b.sale2
        when category in ('ccc') then sale=b.sale3
    end
    as sale
FROM `tableA` AS a
JOIN `tableB` AS b
ON a.store = CAST(b.store AS STRING)

我需要帮助。提前谢谢

您可以使用
大小写
表达式:

select a.store, a.category,
       (case when a.category = 'aaa' then b.sale1
             when a.category in ('bbb', 'ddd') then b.sale2
             when a.category in ('ccc') then b.sale3
        end) as sale
from `tableA` a join
     `tableB` b
     on a.store = cast(b.store as string) ;

实际上,除了
case
表达式之外,您的查询基本上是正确的(尽管CTE是多余的)。
sale=
不合适。
大小写表达式返回一个值。然后可以使用
as
将其分配给列。您可以使用
case
表达式:

select a.store, a.category,
       (case when a.category = 'aaa' then b.sale1
             when a.category in ('bbb', 'ddd') then b.sale2
             when a.category in ('ccc') then b.sale3
        end) as sale
from `tableA` a join
     `tableB` b
     on a.store = cast(b.store as string) ;

实际上,除了
case
表达式之外,您的查询基本上是正确的(尽管CTE是多余的)。
sale=
不合适。
大小写表达式返回一个值。然后可以使用
将其分配给列,因为
下面的是用于BiQquery标准SQL的

下面的解决方案看起来可能过于工程化,但如果您希望将映射规则与代码分开,并且/或者这些规则的数量会使代码变得不可管理,等等,这可能是您的首选方案

#standardSQL
WITH map AS (
  SELECT 'sale1' column, ['aaa'] categories UNION ALL
  SELECT 'sale2', ['bbb', 'ddd'] UNION ALL
  SELECT 'sale3', ['ccc']
)
SELECT a.*, SPLIT(kv, ':')[SAFE_OFFSET(1)] sale
FROM `project.dataset.tableA` a
JOIN `project.dataset.tableB` b
  ON a.store = CAST(b.store AS STRING)
JOIN map m
  ON a.category IN UNNEST(m.categories)
JOIN UNNEST(SPLIT(TRIM(TO_JSON_STRING(b), '{}'))) kv
  ON TRIM(SPLIT(kv, ':')[SAFE_OFFSET(0)], '"') = m.column
如果要将上述代码应用于问题中的样本数据,则输出为

Row store   category    city    sale     
1   11      aaa         xx      0.5  
2   12      bbb         yy      1.25     
3   12      ccc         zz      1.23     
4   13      ddd         xy      0.87     

下面是BiQquery标准SQL的示例

下面的解决方案看起来可能过于工程化,但如果您希望将映射规则与代码分开,并且/或者这些规则的数量会使代码变得不可管理,等等,这可能是您的首选方案

#standardSQL
WITH map AS (
  SELECT 'sale1' column, ['aaa'] categories UNION ALL
  SELECT 'sale2', ['bbb', 'ddd'] UNION ALL
  SELECT 'sale3', ['ccc']
)
SELECT a.*, SPLIT(kv, ':')[SAFE_OFFSET(1)] sale
FROM `project.dataset.tableA` a
JOIN `project.dataset.tableB` b
  ON a.store = CAST(b.store AS STRING)
JOIN map m
  ON a.category IN UNNEST(m.categories)
JOIN UNNEST(SPLIT(TRIM(TO_JSON_STRING(b), '{}'))) kv
  ON TRIM(SPLIT(kv, ':')[SAFE_OFFSET(0)], '"') = m.column
如果要将上述代码应用于问题中的样本数据,则输出为

Row store   category    city    sale     
1   11      aaa         xx      0.5  
2   12      bbb         yy      1.25     
3   12      ccc         zz      1.23     
4   13      ddd         xy      0.87