Обработка строк Teradata (второй пробел)

#sql #string #teradata

#sql #строка #teradata

Вопрос:

Мне очень трудно решить эту, казалось бы, простую задачу:

Цель: создать запрос, который устраняет средний начальный

Пример

 Name
Smith, John A
Jane, Mary S
  

Я хотел бы получить такой результат, как этот:

 Name
Smith, John
Jane, Mary
  

Любые советы о том, как это сделать с помощью Teradata SQL

Я считаю, что решил проблему, хотя и очень плохо:

 SELECT SUBSTR('SMITH, JOHN A', 0, (POSITION(' ' IN 'SMITH, JOHN A')   (POSITION(' ' IN SUBSTR('SMITH, JOHN A',(POSITION(' ' IN 'SMITH, JOHN A'))  1,50)))))
  

Ответ №1:

 select a,
substr(a,1,index(a,' '))|| substr(trim(substr(a,index(a,' '))),1,index(trim(substr(a,index(a,' '))),' ')),
substr(trim(substr(a,index(a,' '))),index(trim(substr(a,index(a,' '))),' ')) last_name
from a
  

Ответ №2:

Задача состоит в том, чтобы убедиться, что ваши имена последовательно отформатированы. ( Last_Name, Given_Name Middle_Initial ) Если это так, вы можете решить эту проблему с помощью рекурсивного SQL. Следующий SQL будет принимать Given_Name Last_Name и возвращать Last_Name . Возможно, вы сможете настроить его для выполнения своей конкретной задачи. (Мои данные образца не были последовательно отформатированы, поэтому я застрял, пытаясь найти второе (или третье) вхождение символа пробела.)

 WITH RECURSIVE cte (FullName, DelimPosition, RecursionLevel, Element, Remainder) AS
(
  SELECT FullName
       , 0 AS DelimPosition_
       , 0 
       , CAST('' AS VARCHAR(128))
       , FullName
    FROM MyDatabase.Persons

  UNION ALL

  SELECT FullName
       , CASE WHEN POSITION(' ' IN Remainder) > 0
              THEN POSITION(' ' IN Remainder)
              ELSE CHARACTER_LENGTH(Remainder)
         END DelimPosition_
       , RecursionLevel   1
       , SUBSTRING(Remainder FROM 0 FOR DelimPosition_   1)
       , SUBSTRING(Remainder FROM DelimPosition_   1)
    FROM cte
   WHERE DelimPosition_ > 1
     AND RecursionLevel < 3 -- Set max depth
)
SELECT FullName
     , CASE WHEN POSITION('amp;' IN Element) = 0
            THEN Element 
            ELSE NULL
       END AS LastName
  FROM cte c
 WHERE RecursionLevel > 2
 ORDER BY FullName;
  

Другим вариантом было бы реализовать UDF, который возвращает самые правые n символов строки. (например RIGHT(FullName, n) )

Если форматирование не является согласованным, тогда мы должны рассмотреть другие, менее изящные варианты.

Надеюсь, это поможет.