【问题标题】:SQL left join on column ignoring first letterSQL左连接忽略第一个字母的列
【发布时间】:2021-05-16 09:08:42
【问题描述】:

我正在尝试使用表 a 中的“order id”和表 b 中的“order ref”来左连接 2 个表。

问题是订单将完全是数字“12345”,订单参考将在相同数字“a12345”之前有一个字母

想知道是否有办法进行连接但忽略表 b 中的字母?

欢迎任何想法

谢谢

【问题讨论】:

    标签: sql database netezza


    【解决方案1】:

    当然。你在 JOIN 中看到的东西是真实的陈述;它们根本不需要与表数据有任何关系

    A JOIN B ON EXTRACT(HOUR FROM NOW()) = 12
    

    这会将 A 中的所有行与 B 中的所有行连接起来,但仅在每天一小时内(您必须在 12:00 到 12:59:59 之间运行它) - 这与表数据无关

    想象一下,连接的工作类似于“A 中的每一行都与 B 中的每一行连接,然后对结果中的每一行评估真值语句。如果为假,则丢弃该行。因此 ON 1=1 是有效并包含所有行,因为它始终为真..


    因此,将 A 中的所有行加入到 B 中,其中 B 是开头带有“a”的行,如下所示:

    A JOIN B ON A.ID = SUBSTR(B.ID, 2, LENGTH(B.ID) - 1))
    

    不过要小心;操作表数据会扼杀索引的使用

    还可以考虑B.ID LIKE CONCAT('_', A.ID)

    【讨论】:

      【解决方案2】:

      如果订单引用总是在订单 ID 后面有一个单字母前缀,那么只需加入前者的子字符串:

      SELECT *
      FROM TableA a
      INNER JOIN TableB b
          ON SUBSTR(b.order_ref, 2, LENGTH(b.order_ref) - 1) = a.order_id;
      

      如果订单 ref 可能有也可能没有那个单字母前缀,您可以尝试在任一条件下加入:

      SELECT *
      FROM TableA a
      INNER JOIN TableB b
          ON b.order_ref = a.order_id OR
             SUBSTR(b.order_ref, 2, LENGTH(b.order_ref) - 1) = a.order_id;
      

      【讨论】:

        【解决方案3】:

        考虑使用 regexp_* 函数套件来提供帮助。

        例如

        select * 
        from A left join B 
        on 
           regexp_extract(A.order_id, ‘^\D*(\d+)’, 1) =
           regexp_extract(B.order_ref, ‘^\D*(\d+)’, 1);
        

        在这种情况下,\D* 表示出现零个或多个非数字字符,后跟一个或多个由括号捕获的数字。这让您在加入期间不忽略任何数字前缀(如果有)

        【讨论】:

          猜你喜欢
          • 2016-09-27
          • 2018-09-15
          • 1970-01-01
          • 2018-10-26
          • 1970-01-01
          • 1970-01-01
          • 2023-03-18
          • 2011-10-18
          • 2017-11-30
          相关资源
          最近更新 更多