如何使用包含所有映射的查找表替换多列中的值?

时间:2019-04-03 09:37:14

标签: sql join google-bigquery

我有一个表,其中包含4列产品代码(以及其他列)。我有另一个表,其中包含一列all_codes和另一列包含代码descriptions

如何将第一张表中的多列代码联接(或替换)到第二张表中的描述?

我已经成功地使用替换功能通过加入tbl1.code1 = tbl2.all_codes来获取我的一列的描述,但是无法使其扩展以供使用

tbl1.code2 = tbl2.all_codes, tbl1.code3 = tbl2.all_codes

表1

    OrderNo  |  Style_code |   Color_code |   Country_code
-------------|-------------|--------------|---------------
     21540   |    abc      |     kdx      |      plo
     21541   |    gcs      |     kdy      |      pla
     21542   |    wer      |     kdz      |      plh
     21543   |    abc      |     kdx      |      pld
     21544   |    gcs      |     kdy      |      plo

表2

 all_codes   |  description
 ------------|-----------------  
    abc      |     plain
    gcs      |     vintage
    wer      |     modern
    kdx      |     white
    kdy      |     gray
    kdz      |     black
    plo      |     USA
    pla      |     Mexico
    plh      |     Canada
    pld      |     Brazil

所需的输出

    OrderNo  |  Style_desc |   Color_desc |   Country_desc
-------------|-------------|--------------|---------------
     21540   |  plain      |  white       |      USA
     21541   |  vintage    |  gray        |      Mexico
     21542   |  modern     |  black       |      Canada
     21543   |  plain      |  white       |      Brazil
     21544   |  vintage    |  gray        |      USA

有人可以帮我找到最好的方法吗?

2 个答案:

答案 0 :(得分:0)

您需要多个join

select t1.orderNo, acs.description as style_desc,
       acc.description as color_desc,
       acco.description as country_desc
from table1 t1 left join
     all_codes acs
     on t1.style_code = acs.code left join
     all_codes acc
     on t1.color_code = acc.code left join
     all_codes acco
     on t1.country_code = acco.code ;

此版本使用left join,以防万一任何值与参考表都不匹配。

答案 1 :(得分:0)

  

有人可以帮助我找到最佳方法吗?

以下选项适用于BigQuery Standard SQL。如果不是最好的-绝对是一个不错的尝试。假设all_codes表不是很大,所以这些代码的数组是可管理的...

#standardSQL
CREATE TEMP FUNCTION code_mapping(code STRING, all_codes ARRAY<STRUCT<all_codes STRING, description STRING>>) AS ((
  SELECT description FROM UNNEST(all_codes) WHERE code = all_codes
));
SELECT OrderNo, 
  code_mapping(Style_code, codes) Style_desc,
  code_mapping(Color_code, codes) Color_desc,
  code_mapping(Country_code, codes) Country_desc
FROM `project.dataset.table1`
CROSS JOIN (SELECT ARRAY_AGG(t) codes FROM `project.dataset.table2` t)

您可以使用问题中的示例数据来进行测试,如上示例所示

#standardSQL
CREATE TEMP FUNCTION code_mapping(code STRING, all_codes ARRAY<STRUCT<all_codes STRING, description STRING>>) AS ((
  SELECT description FROM UNNEST(all_codes) WHERE code = all_codes
));
WITH `project.dataset.table1` AS (
  SELECT 21540 OrderNo, 'abc' Style_code, 'kdx' Color_code, 'plo' Country_code UNION ALL
  SELECT 21541, 'gcs', 'kdy', 'pla' UNION ALL
  SELECT 21542, 'wer', 'kdz', 'plh' UNION ALL
  SELECT 21543, 'abc', 'kdx', 'pld' UNION ALL
  SELECT 21544, 'gcs', 'kdy', 'plo' 
), `project.dataset.table2` AS (
  SELECT 'abc' all_codes, 'plain' description UNION ALL
  SELECT 'gcs', 'vintage' UNION ALL
  SELECT 'wer', 'modern' UNION ALL
  SELECT 'kdx', 'white' UNION ALL
  SELECT 'kdy', 'gray' UNION ALL
  SELECT 'kdz', 'black' UNION ALL
  SELECT 'plo', 'USA' UNION ALL
  SELECT 'pla', 'Mexico' UNION ALL
  SELECT 'plh', 'Canada' UNION ALL
  SELECT 'pld', 'Brazil' 
)
SELECT OrderNo, 
  code_mapping(Style_code, codes) Style_desc,
  code_mapping(Color_code, codes) Color_desc,
  code_mapping(Country_code, codes) Country_desc
FROM `project.dataset.table1`
CROSS JOIN (SELECT ARRAY_AGG(t) codes FROM `project.dataset.table2` t)

有结果

Row OrderNo Style_desc  Color_desc  Country_desc     
1   21540   plain       white       USA  
2   21541   vintage     gray        Mexico   
3   21542   modern      black       Canada   
4   21543   plain       white       Brazil   
5   21544   vintage     gray        USA