Как я могу получить первое второе и третье слово строки в SQL? - PullRequest
0 голосов
/ 03 января 2019

Мне нужен запрос, который извлек бы первое второе и третье слово строки.

У меня примерно 5 слов в каждой строке, и мне нужны только первые три слова из 5 в одной строке (1 строка). Пример "ATV BDSG 232 продолжить с другими словами".

Мне нужны только первые три слова вместе в одном ряду (в одном ряду), например, "ATV BDSG 232" в качестве первого ряда. Таблица содержит около 1000 строк, и в конце я должен снова иметь 1000 строк, но каждая строка должна содержать только первые три слова строки.

Я нашел запрос, который отлично работает для извлечения первых двух, таких как "ATV BDSG", который обсуждался при переполнении стека. Запрос

"SELECT SUBSTRING (field1, 0, CHARINDEX ('', field1, CHARINDEX ('', field1, 0) +1)) С таблицы "

Можем ли мы получить это для извлечения первых трех слов?

Заранее спасибо

Ответы [ 3 ]

0 голосов
/ 03 января 2019

Если вы не хотите создавать выделенную функцию, вы можете использовать последовательные CROSS APPLY s:

SELECT
    T.s,
    FirstSpace.i,
    SecondSpace.j,
    ThirdSpace.k,
    CASE
        When ThirdSpace.k > 0 THEN LEFT(T.s, Thirdspace.k - 1)
        ELSE T.S
    END AS Phrase
FROM t
    CROSS APPLY (SELECT CHARINDEX(' ', T.s, 1)) AS FirstSpace(i)
    CROSS APPLY (SELECT CHARINDEX(' ', T.S, FirstSpace.i + 1)) AS SecondSpace(j)
    CROSS APPLY (SELECT CHARINDEX(' ', T.s, SecondSpace.j + 1)) AS ThirdSpace(k)

дает вам необходимые результаты:

|                   s                    | i | j | k  | phrase           |
|----------------------------------------|---|---|----|------------------|
| ATV BDSG 232 Continue with other words | 4 | 9 | 13 | ATV BDSG 232     |
0 голосов
/ 03 января 2019
 --make some test data

declare @test as nvarchar(100) = 'my test   string  for words';

select 1 id, cast('my test   string  for words' as nvarchar(max)) word into #test;
insert #test (id,word) values (2,'a  b c d e f g hhh   yyyyyy') ;
insert #test (id,word) values (3,'  a required test string  d e f g hhh   yyyyyy') ;
insert #test (id,word) values (4,'a quick test') ;
insert #test (id,word) values (5,'a test') ;
insert #test (id,word) values (6,'last') ;

--break up letters, count the first 3 words
;WITH CTE AS (SELECT 1 x, substring(@test,1,1) charx
             UNION ALL
             SELECT X + 1, substring(@test,x + 1,1) from CTE WHERE x < len(@test) 
             )
             select * from cte c3 where (SELECT count(0) cnt FROM CTE c1 JOIN CTE c2 on c1.x <= c3.x and c1.x + 1 = c2.x and c1.charx =' ' and c2.charx != ' ') < 3



;WITH   tabx as (select id, cast(ltrim(word) as nvarchar(max)) 'word' from #test),    --do some ltrim
        CTE AS (
                SELECT id, 1 x, substring(word,1,1) charx from tabx
                UNION ALL
                SELECT t.id, c.X + 1, substring(t.word,x + 1,1)  
                        from tabx t 
                            JOIN CTE c on c.id =  t.id and x < len(t.word) 
             ),
        disj as
             (select * from cte c3 where 
                        (SELECT count(0) cnt 
                                FROM CTE c1 
                                JOIN CTE c2 on c1.id = c3.id and c1.id = c2.id and c1.x <= c3.x and c1.x + 1 = c2.x and c1.charx =' ' and c2.charx != ' '
                        ) < 3
                ),
        rj as 
            (select disj.id,disj.x, disj.charx z  
                                from disj 
                                where disj.x = 1 
                UNION ALL 
                    select d.id, d.x, r.z + d.charx    
                            FROM rj r 
                            join disj d on r.id = d.id and r.x + 1 = d.x
            )
                select *  
                    from rj r1  
                        cross apply (select max(r2.x) TheRow from rj r2 where r1.id = r2.id) dq
                    where r1.x = dq.TheRow  
                    order by r1.id;

 --delete test data
drop table #test 
0 голосов
/ 03 января 2019

Все просто, SQL Server предоставляет функцию STRING_SPLIT(), что делает это слишком простым

DECLARE @Var VARCHAR(100) = 'ATV BDSG 232 Continue with other words';

SELECT Word
FROM
    (
     SELECT Value AS Word,
            ROW_NUMBER()OVER(ORDER BY (SELECT NULL)) RN
     FROM STRING_SPLIT(@Var, ' ')
    ) T
WHERE RN <= 3;

Но поскольку вы работаете над версией 2012, вам нужно определить свою собственную функцию.

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

DECLARE @Var VARCHAR(100) = 'ATV BDSG 232 Continue with other words';

WITH FW AS
(
  SELECT LEFT(@Var, CHARINDEX(' ', @Var)) FirstWord
),
 SW AS
(
  SELECT LEFT(REPLACE(@Var, FirstWord, ''),
              CHARINDEX(' ', REPLACE(@Var, FirstWord, ''))) SecondWord
  FROM FW
)
SELECT FirstWord,
       SecondWord,
       LEFT(REPLACE(REPLACE(V, FirstWord, ''), SecondWord, ''),
       CHARINDEX(' ', REPLACE(REPLACE(V, FirstWord, ''), SecondWord, ''))
       ) ThirdWord
FROM
    (
     SELECT *, @Var V
     FROM FW CROSS APPLY SW
    ) T

Демо

ОБНОВЛЕНИЕ

Если вы хотите выбрать три первых слова, просто

SELECT SUBSTRING(Str, 0, CHARINDEX(' ', Str, CHARINDEX(' ', Str, CHARINDEX(' ', Str, 0)+1)+1)) Words
FROM Strings

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...