SQL Split function
I'm looking for a way to do this ...
SELECT FirstName, LastName, Split(AddressBlock, ' ', 1), Split(AddressBlock, ' ', 2), PostCode
FROM Contacts
The arguments I want to pass are ...
- 开发者_如何学运维The address
- The separator (current situation requires 2 spaces but this might be a comma or a space followed by a comma) or something else (it varies).
- The address part I want to return (i don't always need all parts of the split result).
I seem to be able to find a few examples of splitting functions about the internet but they return a table containing the entire set of split parts.
My SQL skills aren't that great so I need the answer to be ultra simple. I'm always working with nvarchar data and the function needs to be reusable.
If you want a user-defined function to do this, this should work. Not that pretty, but...
CREATE FUNCTION dbo.SplitStringPart (
@input nvarchar(MAX),
@separator nvarchar(10),
@index int
) RETURNS nvarchar(MAX)
BEGIN
DECLARE @counter int,
@position int,
@oldposition int,
@separatorlength int,
@result nvarchar(MAX)
SET @separatorlength = DATALENGTH(@separator) / 2
IF @separatorlength = 0 RETURN NULL
SET @result = NULL
SET @counter = 1
SET @position = -2
WHILE (@counter <= @index)
BEGIN
SET @oldposition = @position
SET @position = CHARINDEX(@separator, @input, @position + 1)
IF @position = 0 AND @counter < @index
BEGIN
SET @oldposition = 0
BREAK
END
SET @counter = @counter + 1
END
IF @oldposition = 0 AND @position = 0
RETURN NULL
ELSE IF @oldposition < 0
BEGIN
IF @position = 0 AND @index = 1
SET @result = @input
ELSE
SET @result = SUBSTRING(@input, 0, @position)
END
ELSE IF @position <= 0
SET @result = SUBSTRING(@input, @oldposition + @separatorlength, LEN(@input) - @oldposition - @separatorlength)
ELSE
SET @result = SUBSTRING(@input, @oldposition + @separatorlength, @position - @oldposition - @separatorlength)
RETURN @result
END
GO
It's not pretty, but add this to you SQL statement and it should work:
CASE
WHEN charindex(' ', substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))) > 0 THEN substring(AddressBlock, (charindex(' ', AddressBlock) + 1), charindex(' ', substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))) - 1)
ELSE substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))
END AS 'Address 1',
CASE WHEN charindex(' ', substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))) > 0 THEN substring(AddressBlock, charindex(' ', AddressBlock) + charindex(' ', substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))) + 1, Len(AddressBlock))
ELSE ''
END AS 'Address 2'
Here is my version of the answer. This is MUCH faster and robust. No need to fuss around with substrings, charindex, etc.
CREATE FUNCTION [dbo].[SplitArray]
(
@RowToSplit nvarchar(MAX),
@Delimeter nvarchar(MAX)
)
RETURNS @RtnValue table (ID bigint IDENTITY, Data nvarchar(MAX))
AS
BEGIN
DECLARE @xml xml
SET @xml = '<field>' + REPLACE(@RowToSplit, @Delimeter, '</field><field>') + '</field>'
INSERT INTO @RtnValue(data)
SELECT tbl.c.value('.','nvarchar(max)')
FROM @xml.nodes('/field') tbl(c)
RETURN
END
You would simply use the resultant split values in a table, like this:
SELECT Data FROM dbo.SplitArray('this is great',' ')
This will return:
Data
============
this
is
great
精彩评论