Разделение столбца VARCHAR на несколько столбцов - PullRequest
1 голос
/ 04 июня 2019

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

У меня есть только разрешения на чтение. Поэтому я не могу создавать какие-либо функции.

Например:

Имя клиента: Технологический институт Иллинойса

Мой запрос будет вызывать только «Иллинойс» в одном столбце и «Технологический институт» в другом столбце. Рассматривая разделитель как «пробел», я хочу разделить каждое слово на отдельные столбцы. Я не уверен, как определить 2-й пробел и дальнейшие пробелы.

Я также пытался использовать функцию 'parsename', но чувствую, что это затруднит очистку данных.

select name, 
left (name, CHARINDEX(' ', name)) as f,
substring(name, CHARINDEX(' ', name)+1, len(name)) as s
from customer

Ответы [ 2 ]

0 голосов
/ 04 июня 2019

РЕДАКТИРОВАТЬ: Это работает только для SQL Server 2016 и выше. OP имеет SQL Server 2014.

На самом деле не существует хорошего способа сделать это, но вот один метод, который может работать для вас, модифицированный из примера здесь :

create table #customer (id int, name nvarchar(max))

insert into #customer
values  (1, 'Illinois Institute of Technology'), 
        (2, 'The City University of New York'), 
        (3, 'University of the District of Columbia'), 
        (4, 'Santa Fe University of Art and Design')

;   
with c as(
select id, name
      ,value
      ,row_number() over(partition by id order by (select null)) as rn
from #customer
cross apply string_split(name, ' ') as bk
)
select id, name
      ,[1]
      ,[2]
      ,[3]
      ,[4]
      ,[5]
      ,[6]
from c
pivot(
    max(value)
    for rn in([1],[2],[3],[4],[5],[6])  
) as pvt

drop table #customer

Обратите внимание на несколько вещей:

  1. Вы должны явно объявить столбцы в выводе. Вы можете создать слишком сложный динамический SQL, который будет генерировать столько имен столбцов, сколько вам нужно, но это затруднит исправление проблем и внесение изменений, и вы, вероятно, не получите такую ​​же оптимизацию запросов.
  2. Из-за (1) вы просто выбросите слова, если их слишком много, чтобы соответствовать количеству столбцов, которые вы определили. Смотрите последний пример, id = 4.
  3. Остерегайтесь других методов, которые могут не поддерживать порядок в ваших словах или пропустить повторяющиеся слова, например. «из» в примере id = 3.
0 голосов
/ 04 июня 2019

Вы не упоминаете, что планируете делать с данными после их получения.Поскольку у вас есть только права на чтение, вы не можете сохранить его в таблице.Что-то, о чем вы, возможно, и не задумывались, - это создать локальную базу данных, в которой у вас есть права на запись, и выполнять свою работу там.Самый простой способ - получить копию базы данных, но вы также можете получить доступ к базе данных только для чтения, используя полные имена.

Что касается ваших потребностей разделения строк, я могу указать вам отличный способ разделения.струны, созданные джентльменом по имени Джефф Моден.Вы можете найти статью, обсуждающую это, а также ссылку на код здесь:

Tally OH!Улучшенная функция CSV Splitter для SQL 8K

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

Код создает функцию, но у вас нет разрешения делать это.придется удалить мясо из функции и использовать его напрямую.

Я постараюсь дать небольшой обзор подхода, с которого можно начать.

Суть подхода - этоTally Table.Если вы не знакомы с этим термином (он также называется таблицей чисел), это, в основном, таблица, в которой каждая строка содержит целое число, а строки - это набор всех целых чисел в некотором диапазоне, обычно довольно больших.Так как Tally Table помогает разбивать строки?Волшебство происходит, соединяя таблицу подсчета с таблицей, содержащей строки, которые нужно разделить, и используя предложение where для идентификации разделителей, просматривая 1-символьные подстроки, проиндексированные по номерам таблицы подсчета.Затем естественные операции на основе множеств SQL Server осуществляют поиск всех разделителей за один раз, а ваш список выбора затем извлекает подстроки, заключенные в скобки.Это действительно довольно умно и очень быстро.

Когда вы попадаете в код, первая часть функции может выглядеть очень странно (потому что это так), но это необходимо, поскольку у вас есть только права на чтение.В основном он использует функциональность Common Table Expression (CTE) SQL Server для создания внутренней подсчетной таблицы на лету, используя некрасивую логику, которую вам на самом деле не нужно понимать (но если вы хотите разобраться, это умно, даже если этонекрасиво).Поскольку таблица является только локальной для запроса, она не будет нарушать ваши разрешения только для чтения.

Она также использует CTE для представления начального индекса и длины подстрок с разделителями, поэтому окончательный запрос довольно прост, получая строки сномер строки, за которым следует строка, отделенная от исходных данных.

Надеюсь, это поможет вам в вашей задаче - это действительно хороший инструмент для использования в вашем наборе инструментов.

Редактировать: Iтолько что понял, что вы хотите, чтобы ваш вывод был в отдельных столбцах, а не в строках.Это немного сложнее, так как каждый столбец, который вы разделяете, может создать различное количество строк, а также, ваши столбцы будут нуждаться в именах.Если вы уже знаете имена столбцов и знаете количество выходных строк, это будет проще, но все же сложно.Данные строки из разделителя могут быть изменены для предоставления идентификатора строки, из которой были получены данные, и номеров строк, которые могут помочь в создании произвольных имен столбцов, если они вам нужны, но большая проблема заключается в том, что при наличии только прав на чтение вы найдете обработкувсе пошагово, довольно сложно - CTE могут быть использованы для этого еще дальше, но ваш код, скорее всего, будет довольно запутанным, если требования не будут достаточно простыми.

...