SPLIT или TRIM Text (String, Varchar) в MSSQL Server

Я хочу разделить или «обрезать» поле (имя) на моем SQL-сервере в таблице... Но я получаю ошибки всеми испробованными способами.

Пример кода ошибки для моего личного Заявления о лучшем способе:

Столбец SingleWords или пользовательский агрегат "SingleWords.value" не найден, или имя неоднозначно.

Например:

У меня есть поле, которое называется: «имя». Это поле включает имя и фамилию (разделенные CR/LF или пробелом).

Для моего заявления мне нужно разделить имя на два разных поля. Но я хочу использовать только SQL-Management Studio.

Это возможно?

Мой уровень совместимости SQL равен "130"...

я попробовал следующее заявление для примера:

SELECT NAME FROM dbo.CRM_IM_X STRING_SPLIT(Name, CHAR(13)+CHAR(10)) WHERE RTRIM(NAME) <> '';

ИЛИ (мой личный лучший способ):

SELECT CAST('<x>' + REPLACE(NAME,CHAR(13)+CHAR(10),'</x><x>') + '</x>' AS XML) AS SingleWords
    FROM dbo.CRM_IM_X

SELECT SingleWords.value('x[1]','varchar(max)') AS part1
      ,SingleWords.value('x[2]','varchar(max)') AS part2
FROM dbo.CRM_IM_X

Часть 1 для имени,

Часть 2 для фамилии,

CHAR(13)+CHAR(10) для CR/LF.

ПРИМЕР ВВОДА ДАННЫХ:

DECLARE @tbl TABLE(NAME VARCHAR(100));
INSERT INTO @tbl VALUES('Jane
Doe'),('John
Doe');

Но я застрял в объединении этих двух операторов Select вместе...


person Xavi Lux    schedule 09.04.2018    source источник
comment
Пожалуйста, укажите свою версию SQL Server.   -  person McNets    schedule 09.04.2018
comment
пожалуйста, предоставьте образцы данных и вывод   -  person Kaval Patel    schedule 09.04.2018
comment
Не помечайте MySQL для вопроса о SQL Server, это разные СУБД.   -  person Larnu    schedule 09.04.2018
comment
С другой стороны, вы говорите, что у вас есть ошибки. Пожалуйста, не могли бы вы отредактировать свой пост и включить их, пожалуйста?   -  person Larnu    schedule 09.04.2018
comment
просто глядя на ваши выборочные данные, первая проблема в том, что у вас есть один человек с титулом, а затем второй без него. Это сразу создает проблему. Означает ли это, что вы также можете иметь следующие значения? Mr Smith, Mr George W Bush, если у вас нет согласованности с вашими данными, вы не добьетесь этого. Если вы не можете делать безопасные предположения, вы получите неправильные результаты.   -  person Larnu    schedule 09.04.2018
comment
я уже думал, что ... я редактирую свое заявление, CR / LF только между именем и фамилией. Может тогда можно? если вы попробуете выполнить следующую инструкцию: {SELECT CAST('‹x›' + REPLACE(NAME,CHAR(13)+CHAR(10),'‹/x›‹x›’) + ’‹/x›’ AS XML) AS SingleWords FROM dbo.CRM_IM_X} Вы видите, что x стоит в правильном положении... После этого я хочу попытаться поместить это в собственные поля со следующим выражением: {SELECT SingleWords.value('x[1]', 'varchar(max)') AS part1 ,SingleWords.value('x[2]','varchar(max)') AS part2 FROM dbo.CRM_IM_X} Мне нужны эти два шага в одном выражении?   -  person Xavi Lux    schedule 09.04.2018


Ответы (4)


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

DECLARE @tbl TABLE(NAME VARCHAR(100));
INSERT INTO @tbl VALUES('Jane
Doe'),('John
Doe');

WITH Replaced AS(
    SELECT REPLACE([NAME],CHAR(13),'') AS [Name]
    FROM @tbl)
SELECT LEFT([name], CHARINDEX(CHAR(10),[Name]) -1) AS FirstName,
       RIGHT([name], LEN([Name]) - (CHARINDEX(CHAR(10),[Name]))) AS Surname
FROM Replaced;

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

DECLARE @tbl TABLE(NAME VARCHAR(100));
INSERT INTO @tbl VALUES('Jane
Doe'),
('John
Doe'),
('Mr
Smith'),
('Mr
Joe
Bloggs'),
('George
W.
Bush'),
('Sir
Friedrich
Harold
Smithe
III');

WITH Replaced AS(
    SELECT REPLACE([NAME],CHAR(13),'') AS [Name]
    FROM @tbl)
SELECT LEFT([name], CHARINDEX(CHAR(10),[Name]) -1) AS FirstName,
       RIGHT([name], LEN([Name]) - (CHARINDEX(CHAR(10),[Name])))
FROM Replaced;
person Larnu    schedule 09.04.2018
comment
У вас есть идея, как мы можем решить проблему с заголовком в полях? Можно ли работать с шаблоном if? - person Xavi Lux; 10.04.2018
comment
@XaviLux на SQL-сервере, честно говоря, нет. Ложь, которой верят программисты в отношении имен. Пока не установлены очень строгие правила, лучше всего при разделении имени будет человек (слишком много переменных, чтобы их можно было определить программно); и если бы у вас были эти правила, вы, вероятно, не были бы в том положении, в котором находитесь. :) - person Larnu; 10.04.2018
comment
в этом случае у меня есть список с возможными комбинациями заголовков. В этом поле (catalogEntry) около 20 наименований. Так можно ли создать правило в SQL? - person Xavi Lux; 10.04.2018
comment
@XaviLux Нет, потому что в ваших исходных данных у вас был кто-то с титулом и без имени; так что я уже знаю, что нет никаких правил. Под очень строгим я буквально подразумеваю очень строгий. Если имя может иметь или не иметь имя, это уже 1 слишком много переменных. - person Larnu; 10.04.2018
comment
вы правы, я не знал, что иногда в поле может отсутствовать и фамилия... Спасибо! - person Xavi Lux; 10.04.2018

Следующий код будет вам полезен,

// You can use the Common Table Expression(CTE).
;WITH Split_Names (SingleWords)
AS
(
   SELECT CONVERT(XML,'<Names><name>'  
                      + REPLACE(Names,' ', '</name><name>') 
                      + '</name></Names>'
                 ) AS SingleWords
   FROM ExampleTable
)

SELECT  SingleWords.value('/Names[1]/name[1]','varchar(100)') AS part1,    
        SingleWords.value('/Names[1]/name[2]','varchar(100)') AS part2,
        SingleWords.value('/Names[1]/name[3]','varchar(100)') AS part3
FROM Split_Names

Демонстрация скрипта SQL

person Abhilash Ravindran C K    schedule 09.04.2018

Спасибо за помощь! @Larnu Вы правы, если CR / LF также используется для названия, у вас возникнет эта проблема, если я использую только 2 части. Но если я получу третью часть и четвертую часть, я думаю, что это возможно, когда синтаксис имени каждый раз выглядит так: Название (CR / LF), Имя (CR / LF), фамилия

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

следующий код также работает сейчас. В этом примере каждое слово до и после CR/LF помещается в одно новое поле:

DECLARE @tbl TABLE(NAME VARCHAR(100));
INSERT INTO @tbl VALUES('Jane
Doe'),
('John
Doe'),
('Mr
john
Smith'),
('Mr
Joe
Bloggs'),
('George
W.
Bush'),
('Sir
Friedrich
Harold
Smithe
III');

WITH Splitted AS
(
SELECT CAST('<x>' + REPLACE(NAME,CHAR(13)+CHAR(10),'</x><x>') + '</x>' AS XML) AS SingleWords
    FROM @tbl
)
SELECT SingleWords.value('x[1]','varchar(max)') AS part1
      ,SingleWords.value('x[2]','varchar(max)') AS part2
      ,SingleWords.value('x[3]','varchar(max)') AS part3
      ,SingleWords.value('x[4]','varchar(max)') AS part4
FROM Splitted
person Xavi Lux    schedule 09.04.2018

Вы можете использовать простой код, приведенный ниже:

SELECT SUBSTRING(Name, 1, CHARINDEX(' ', Name)) AS PART1, 
       SUBSTRING(Name, CHARINDEX(' ', Name), LEN(Name)) AS PART2 
FROM ExampleTable

Я добавил свой SQLFiddle с этим решением. Вы можете проверить это. Удачи!

person Vignesh VS    schedule 09.04.2018
comment
Благодарю вас! @vignesh - person Xavi Lux; 09.04.2018