【问题标题】:Comparing one column values with spaces in between with another one in Oracle PL/SQL在 Oracle PL/SQL 中将一列值与另一列之间的空格进行比较
【发布时间】:2018-12-01 21:53:58
【问题描述】:

我需要将一列值与下表“BRAND”中的另一列值进行比较。我尝试单独考虑两列之间的字符串长度,但尽管如此.. 列中的值不同,因此它给出的结果不正确。

表品牌:

ID       brand_1             brand_2        Status
---------------------------------------------------   
1        SAC                 SAC            True
2        APP BBB             BBB APP        True
3        ABC OND DEG         DEG ABC OND    True
4        GIF                 APP GIF        False
5        GHY PPA             GHY PPA ABC    False
6        MNC CGA IPK         GIT ABC ITY    False

我需要返回 False 的行,因为brand_1 和brand_2 列之间没有匹配。数据中不存在 Status 列;我在这里添加它是为了演示哪些行被认为是“错误的”并且应该返回。该列也不应该存在于输出中。

输出:

 ID        brand_1             brand_2     
------------------------------------------- 
4          GIF                 APP GIF       
5          GHY PPA             GHY PPA ABC   
6          MNC CGA IPK         GIT ABC ITY   

请帮帮我。

【问题讨论】:

  • 什么是:(1) Oracle 版本(如 11.2.0.4 或 12.2.0.1 - 用select * from v$version 查找;(2) 您的预期知识水平?您可以使用 user-定义的类型、嵌套表、lateral 子句等?然后:ID = 4,在brand_2 下,中间有两个空格;这是错误的吗?或者两个空格算作它们之间的null?在换句话说:AAA BBBBBB AAA 是否被认为是相同的,即使它们中间有不同数量的空格?
  • 嗨,Mathguy,对于 ID =4 ,应该只有一个空格而不是两个空格。错误地,它出现了两个空格。是的,AAA BBB 和 BBB AAA 被认为是相同的。
  • Oracle 版本:12.1.0.2.0
  • 嗨 Mathguy,我正在执行相同的操作并且能够看到结果。非常感谢。我正在对数据进行更多测试。以防万一,如果我只想显示下面没有“状态”的输出并返回任何错误的内容。请告诉我该怎么做。 ID 品牌_1 品牌_2 ----------------------------------------------- ---- 4 GIF APP GIF 5 GHY PPA GHY PPA ABC 6 MNC CGA IPK GIT ABC ITY
  • 抱歉,我无法为表格提供正确的格式

标签: string oracle compare


【解决方案1】:

这是一种方法(不是最快的,但易于编写和维护)。这个想法是将每个输入字符串拆分为其组件,按字母顺序对它们进行排序,然后重新组合它们。我使用lateral(因此每一行都独立于其他行处理)、JSON 拆分字符串的技巧和LISTAGG 将它们重新组合在一起。

with
  brand (id, brand_1, brand_2) as (
    select 1, 'SAC'        , 'SAC'         from dual union all
    select 2, 'APP BBB'    , 'BBB APP'     from dual union all
    select 3, 'ABC OND DEG', 'DEG ABC OND' from dual union all
    select 4, 'GIF'        , 'APP GIF'     from dual union all
    select 5, 'GHY PPA'    , 'GHY PPA ABC' from dual union all
    select 6, 'MNC CGA IPK', 'GIT ABC ITY' from dual
  )
select id, brand_1, brand_2,
       case when b1 = b2 then 'True' else 'False' end as status
from   brand,
       lateral( select listagg(token, ' ') within group (order by token) as b1
                from json_table( '["' || replace(brand_1, ' ','","') || '"]',
                                 '$[*]'  columns(token varchar2 path '$'))
              ),
       lateral( select listagg(token, ' ') within group (order by token) as b2
                from json_table( '["' || replace(brand_2, ' ','","') || '"]',
                                 '$[*]'  columns(token varchar2 path '$'))
              )
;

ID BRAND_1     BRAND_2     STATUS
-- ----------- ----------- ------
 1 SAC         SAC         True 
 2 APP BBB     BBB APP     True 
 3 ABC OND DEG DEG ABC OND True 
 4 GIF         APP GIF     False
 5 GHY PPA     GHY PPA ABC False
 6 MNC CGA IPK GIT ABC ITY False

Edit:要在 edited 问题中获得所需的结果,请从 SELECT 子句中删除 case 表达式,并在以下位置添加 WHERE 子句查询结束:... where b1 != b2(假设输入的字符串不能为空,如果可以为空,则需根据业务需要处理)。

【讨论】:

  • 嗨,Mathguy,Output 必须返回 False 状态记录,如下所示。我也不需要显示 Status 列:请告诉我该怎么做。我感谢您的帮助。 ID brand_1 brand_2 -------------- ------------------------- 4 GIF APP GIF 5 GHY PPA GHY PPA ABC 6 MNC CGA IPK GIT ABC ITY
  • @Anitha - 我希望你能够回答你自己的问题 - 它们都是非常基础的。如果您只想保留b1 != b2 所在的行,则在查询的最后添加where 子句(where b1 != b2);如果您不想要STATUS 列,请从SELECT 子句中删除相应的代码(case 表达式)。
  • 是的,我能做到。不用担心!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
相关资源
最近更新 更多