6

I have string like this " This is a hello world example"

Now I want first two words of the sentence as my output in SQL Server. i.e. This is .

Another example: Original sentence : "Complete word exercise" Output: Complete word

Zerotoinfinity
  • 6,290
  • 32
  • 130
  • 206

3 Answers3

17

You can use a query as follows:

DECLARE @d nvarchar(100)
SET @d = 'Complete word exercise'
SELECT SUBSTRING(@d, 0, CHARINDEX(' ', @d, CHARINDEX(' ', @d, 0)+1))

Or alternatively when used in a query:

SELECT SUBSTRING(field1, 0, CHARINDEX(' ', field1, CHARINDEX(' ', field1, 0)+1)) 
FROM Table
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Kadir Sümerkent
  • 474
  • 3
  • 10
  • I am new to SQL SERVER and I feel amaze that people can think like this. great ! Thanks – Zerotoinfinity Dec 07 '10 at 12:17
  • Can you please explain me why you used +1 in the above statement ? – Zerotoinfinity Dec 07 '10 at 12:34
  • 1
    I used +1 to include the second word in result. If you don't use +1 there, query will not include the second word for the function charindex() returns the exact position of the char you are searching for. Please also keep in mind that the sample above will not function if the field / variable does not contains 2 ' ' characters. – Kadir Sümerkent Dec 07 '10 at 13:33
  • i have a problem with this. Where variable has only two words. THis funcion return null value. But this is error. Because is had two words what id need ;) – ms_devel Mar 09 '14 at 14:39
9

Many solutions will break for any strings that have less than 2 words, which is increasingly likely for people hoping to parse the first n number of words.

Let's first look at the query, and then how we can tell if it actually evaluated correctly.
For that, we need to nest multiple CHARINDEX statements, which take the following params:

CHARINDEX( expressionToFind , expressionToSearch [ , start_location ] )

Charindex will return the first index where it finds the specific string. What we keep doing is kicking the ball down the road by adding in a start_location equal to the first found instance +1 so it'll find the 2nd, 3rd, 4th instance, etc. Also, instead of SUBSTRING(@str, 0,... we can just use LEFT(@str,... to capture the first portion of the string, but calculating how far deep to go is the hard part anyway:

DECLARE @string VARCHAR(1000) = 'One Two Three';
SELECT LEFT(@string, CHARINDEX(' ', @string,
                     CHARINDEX(' ', @string,
                     CHARINDEX(' ', @string,
                     CHARINDEX(' ', @string)+1)+1)+1))

But this will fail if we don't have the minimum number of words:
Technically, it'll just keep looping around infinitely. Once it runs out of spaces, it'll start indexing again from the beginning

Char Index Demo

Pop quiz... what will the above query resolve to? Hover below for answer

SELECT LEFT('One Two Three', 3) -- 'One'

In the solution in Extracting a specific number of words from a string in sql, we can check that the last CHARINDEX produced a non-zero value, meaning it hit a space at that level of depth. But also, since the nested charindex is kind of unwieldy, we can get at that information at little more directly by counting the number of occurrences of a certain substring in a SQL varchar?

So the final solution should look like this to grab the first 4 words:

DECLARE @string VARCHAR(1000) = 'One Two Three Four Five Six';

SELECT CASE WHEN LEN(@string)-LEN(REPLACE(@string, ' ', '')) < 4 
            THEN @string
            ELSE LEFT(@string, CHARINDEX(' ', @string,
                               CHARINDEX(' ', @string,
                               CHARINDEX(' ', @string,
                               CHARINDEX(' ', @string)+1)+1)+1))
       END

If there are less than 4 spaces, we'll just return the whole string. For more than four, we'll find the position of the 4th space and return the left portion of the string all the way to that position

KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • It solves the crucial problem the accepted solution has, but the way you answered is not very likeable to me. It looks like a blog post or a story rather than a SO answer. – Haggra Jun 13 '18 at 06:20
  • 1
    @Haggra, fair enough. There is some superlative color commentary, but Stack Overflow serves a wide array of audiences and capacities. Explanatory tangents that aren't helpful for some might be required for others. And since the defect of the existing answers wasn't a clear understanding of what was happening under the hood and what those methods actually *did*, it seemed helpful to explain all parts of the answer rather than just give away the solution in isolation. Especially since the composition of the solution will need to change when people's requirements change. – KyleMit Jun 13 '18 at 13:39
  • 1
    In short, I think the format is exactly what we'd ideally want out of a good and explanatory SO answer, and is very likeable to me, but you're definitely entitled to your own preferences as to what your expectations are when finding technical solutions from strangers on the internet. – KyleMit Jun 13 '18 at 13:41
  • I like the answers here cold and concise. I might not get them the first time I read them but that's the thing about being concise, I can read again very quickly. But as you have mentioned, this is absolutely personal preference and your answer might serve others much better than an answer that I would like. Mine was not a critism, but merely a comment. Your answer helped me greatly otherwise. – Haggra Jun 18 '18 at 10:21
  • 1
    Be aware that every space is counted as a word. So 'One Two Three Four Five Six' gives 'One Two Three' because there are two spaces between "One" and "Two". This site has a neat trick for [removing multiple spaces](http://burnignorance.com/database-tips-and-tricks/remove-multiple-spaces-from-a-string-using-sql-server/). SET @TestString= REPLACE(REPLACE(REPLACE(@TestString,’ ‘,’ %’),’% ‘,”),’%’,”) – David Coster Dec 03 '18 at 05:38
  • How would I go about this if I had to get the first 100 or 1000 words? Do I just extend this solution, or is there a more compact way of doing it? – Rezic Aug 27 '19 at 08:30
1

ORACLE ONLY - You can also use INSTR like this:

SELECT SUBSTR(colName, 0, INSTR(colName,' ',1,2)) FROM table

Note: If row data has less than 2 words, empty row will be returned

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Yusuf K.
  • 4,195
  • 1
  • 33
  • 69