【问题标题】:How can you figure out if Column A contains something from Column B?您如何确定 A 列是否包含 B 列中的某些内容?
【发布时间】:2019-02-11 16:30:16
【问题描述】:

我一直在想办法从表 A 列 A 与表 B 列 A 中获取信息,例如:

TableA
Name
abcd_1234_efgh
zxcdde_gets_3214_
jkil_uelso_5555_aseil
uuuu_kkkk_iiii_3333

TableB
ID    
1234          
3214           
5555      
3333

我尝试从表 A 到表 B 执行 INNER JOIN,然后执行 WHERE TableA.A LIKE TableB.B,但我认为我错过了使其工作的部分。

SELECT
    a.Name,
    b.ID
FROM
    TableA a

INNER JOIN
    TableB b
ON
    a.Name LIKE CAST(b.ID AS STRING)

我想要的结果是:

Name                      ID
abcd_1234_efgh            1234
zxcdde_gets_3214_         3214
jkil_uelso_5555_aseil     5555
uuuu_kkkk_iiii_3333       3333

但目前我没有得到任何结果。我相信我遗漏了一些东西,或者可能正在考虑错误的方法来获得所需的结果。任何帮助将不胜感激!

-Maykid

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

    你很接近。我认为这适用于 BigQuery:

    SELECT a.Name, b.ID
    FROM TableA a INNER JOIN
         TableB b
         ON a.Name LIKE CONCAT('%', CAST(b.ID AS STRING), '%');
    

    但你可能真的想要:

    SELECT a.Name, b.ID
    FROM TableA a CROSS JOIN
         UNNEST(SPLIT(a.Name, '_')) namepart JOIN 
         TableB b
         ON namepart = CAST(b.ID AS STRING);
    

    这看起来像是名称的每个部分,并允许 BigQuery 进行等式连接 - 这应该更具可扩展性。

    【讨论】:

    • 正是我所需要的,两者都完美地工作,谢谢!!
    【解决方案2】:

    以下是 BigQuery 标准 SQL

    #standardSQL
    SELECT *
    FROM `project.dataset.tableA`
    CROSS JOIN `project.dataset.tableB`
    WHERE REGEXP_CONTAINS(Name, id)   
    

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

    #standardSQL
    WITH `project.dataset.tableA` AS (
      SELECT 'abcd_1234_efgh' Name UNION ALL
      SELECT 'zxcdde_gets_3214_' UNION ALL
      SELECT 'jkil_uelso_5555_aseil' UNION ALL
      SELECT 'uuuu_kkkk_iiii_3333' 
    ),  `project.dataset.tableB` AS (
      SELECT '1234' id UNION ALL          
      SELECT '3214' UNION ALL           
      SELECT '5555' UNION ALL      
      SELECT '3333' 
    )
    SELECT *
    FROM `project.dataset.tableA`
    CROSS JOIN `project.dataset.tableB`
    WHERE REGEXP_CONTAINS(Name, id)   
    

    结果

    Row Name                    id   
    1   abcd_1234_efgh          1234     
    2   zxcdde_gets_3214_       3214     
    3   jkil_uelso_5555_aseil   5555     
    4   uuuu_kkkk_iiii_3333     3333     
    

    注意:使用REGEXP_CONTAINS 为您提供了强大的正则表达式,但它有点贵,因此您可以使用STRPOS(),如下例所示

    #standardSQL
    SELECT *
    FROM `project.dataset.tableA`
    CROSS JOIN `project.dataset.tableB`
    WHERE STRPOS(Name, id) > 0   
    

    快速更新:

    我刚刚意识到 id 在您的问题中不是 STRING 而是 INT - 所以:

    REGEXP_CONTAINS(Name, id) 应替换为 REGEXP_CONTAINS(Name, CAST(id AS STRING))
    STRPOS(Name, id) 也一样

    【讨论】:

    • 两个版本都适合我,我希望我能给出多个正确答案,因为两者都有效!非常感谢!
    【解决方案3】:

    鉴于您的数据结构,也许这样的东西会有所帮助(注意SAFE_CAST 的应用):

    select name, c, t2.number from (
      select t1.name, split(t1.name, "_") splitted from TableA t1
    ), unnest(splitted) c
    left join TableB t2 on t2.number = SAFE_CAST(c as int64)
    where number is not null
    

    【讨论】:

      猜你喜欢
      • 2017-05-21
      • 2011-06-20
      • 2019-06-13
      • 2012-07-04
      • 2012-09-04
      • 2019-11-17
      • 2013-07-08
      • 1970-01-01
      • 2023-03-21
      相关资源
      最近更新 更多