Oracle SQL Выберите разделить «Город, штат» на два столбца (с некоторыми экземплярами только штат и без запятой) и обрезать пробелы - PullRequest
0 голосов
/ 04 февраля 2020

Я видел это решение для данных, которые всегда имеют запятые, но, кажется, не могут заставить это работать, когда нет запятых.

Данные поступают из поля "location", которое выглядит следующим образом ... (где некоторые данные - "город, штат", а другие строки - "штат" без указания города).

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

Я пытаюсь получить их в два столбца [Город] и [ 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] и для NULL в столбце [City].

Последний маленький момент - как очистить данные location_str, которые содержат конечные и ведущие пробелы в базе данных (сгенерированные где-то еще).

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

Я могу попробовать это завтра, но могу ли я обернуть REGEXP_SUBSTR в забаву TRIM c? будет ли работать над этим ...

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

Ответы [ 3 ]

1 голос
/ 04 февраля 2020

Вам даже не нужны регулярные выражения для ваших требований; стандартные строковые функции, такие как instr и substr, работают быстрее и отлично работают в этой ситуации.

Предложение WITH не является частью запроса; скорее я включаю его только для генерации тестовых данных. Удалите его и выполните запрос (начиная с select location_str, ...) к вашей фактической таблице.

Как вы и предполагали, 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   
0 голосов
/ 04 февраля 2020

Вы можете добавить запятую к началу значения, если запятая отсутствует, и тогда она будет работать с вашим текущим решением:

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)

Cheers !!

0 голосов
/ 04 февраля 2020

Я бы порекомендовал 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
...