Oracle SQL Select 将 "City, State" 拆分为两列(带有一些仅状态且没有逗号的实例)和 Trim 空格

Oracle SQL Select Split "City, State" to two columns (w/ some instances of just state and no comma) and Trim whitespaces

我见过这种数据解决方案总是有逗号,但在没有逗号的情况下似乎无法正常工作。

数据来自 "location" 字段,看起来像这样...(其中一些数据是 "city, state",其他行是 "state",没有列出城市)。

[location_str]
 Boston, MA
 Miami, FL
 MO
 AK
Fairbanks, AK

我正在尝试将它们添加到两列 [City] 和 [State]。

此代码几乎可以工作...

SELECT  REGEXP_SUBSTR (location_str, '[^,]+', 1, 1)    AS City,
        REGEXP_SUBSTR (location_str, '[^,]+', 1, 2)    AS State
FROM    Locations_Table

结果是……

[City]      [State]
 Boston      MA
 Miami       FL
 MO          NULL
 AK          NULL
 Fairbanks   AK

很接近,我只需要在 [State] 列中结束带有 STATE 且没有逗号的行,并在 [City] 列中结束 NULL。

最后一点是如何清理 location_str 数据库中包含尾随和前导空格的数据(在其他地方生成)。

[location_str]
" Fairbanks, AK"
"Fairbanks, AK      "
"DC"
"DC      "
"DC   "

我明天可以试试,但是我可以将 REGEXP_SUBSTR 包装在 TRIM 函数中吗?下面的工作会在这个...

TRIM(REGEXP_SUBSTR (location_str, '[^,]+', 1, 1)) AS City

我会推荐一个 case 表达式:

SELECT (CASE WHEN location_str LIKE '%,%'
             THEN REGEXP_SUBSTR(location_str, '[^,]+', 1, 1)    
        END) AS City,
       (CASE WHEN location_str LIKE '%,%'
             THEN REGEXP_SUBSTR(location_str, '[^,]+', 1, 2)
             ELSE location_str
        END) AS State
FROM Locations_Table

如果根本没有逗号,您可以在值的开头添加逗号,然后它将适用于您当前的解决方案:

SELECT  REGEXP_SUBSTR (location_str, '[^,]+', 1, 1)    AS City,
        REGEXP_SUBSTR (location_str, '[^,]+', 1, 2)    AS State
FROM    
(Select case when instr(location_str,',') = 0 then ' ,' end || location_str as location_str
From locations_Table)

干杯!!

您甚至不需要正则表达式来满足您的要求;标准字符串函数,如 instrsubstr,速度更快,并且它们在这种情况下工作得很好。

WITH 子句不是查询的一部分;相反,我包含它只是为了生成测试数据。删除它,然后 运行 查询(从 select location_str, ... 开始)在您实际的 table.

如您所料,TRIM(...) 可用于每个结果子字符串两侧的 trim 空格。请注意:这不会处理名称 中的空格 ,例如 'San Francisco''North Carolina'。如果需要,这些也可以处理,但需要多做一些工作。

with
  test_data (location_str) as (
    select 'Boston, MA'          from dual union all
    select '   Miami ,  FL  '    from dual union all
    select 'MO'                  from dual union all
    select '     AK'             from dual union all
    select 'Fairbanks   , AK   ' from dual
  )
select location_str,
       trim(substr(location_str, 1, instr(location_str, ',') - 1)) as city,
       trim(substr(location_str, instr(location_str, ',') + 1))    as state
from   test_data
;

LOCATION_STR        CITY                STATE              
------------------- ------------------- -------------------
Boston, MA          Boston              MA                 
   Miami ,  FL      Miami               FL                 
MO                                      MO                 
     AK                                 AK                 
Fairbanks   , AK    Fairbanks           AK