How to parse a string and create several columns from it?
SELECT substring(NameValue, 1, charindex('_', NameValue)-1) AS Names,
substring(NameValue, charindex('_', NameValue)+1, LEN(NameValue)) AS Values
FROM Table
EDIT:
Something like this put in a function or stored procedure combined with a temp table should work for more than one line, depending on the line delimiter you should also remove CHAR(13)
before you start:
DECLARE @helper varchar(512)
DECLARE @current varchar(512)
SET @helper = NAMEVALUE
WHILE CHARINDEX(CHAR(10), @helper) > 0 BEGIN
SET @current = SUBSTRING(@helper, 1, CHARINDEX(CHAR(10), @helper)-1)
SELECT SUBSTRING(@current, 1, CHARINDEX('_', @current)-1) AS Names,
SUBSTRING(@current, CHARINDEX('_', @current)+1, LEN(@current)) AS Names
SET @helper = SUBSTRING(@helper, CHARINDEX(CHAR(10), @helper)+1, LEN(@helper))
END
SELECT SUBSTRING(@helper, 1, CHARINDEX('_', @helper)-1) AS Names,
SUBSTRING(@helper, CHARINDEX('_', @helper)+1, LEN(@helper)) AS Names
How do I split a delimited string so I can access individual items?
You may find the solution in SQL User Defined Function to Parse a Delimited String helpful (from The Code Project).
You can use this simple logic:
Declare @products varchar(200) = '1|20|3|343|44|6|8765'
Declare @individual varchar(20) = null
WHILE LEN(@products) > 0
BEGIN
IF PATINDEX('%|%', @products) > 0
BEGIN
SET @individual = SUBSTRING(@products,
0,
PATINDEX('%|%', @products))
SELECT @individual
SET @products = SUBSTRING(@products,
LEN(@individual + '|') + 1,
LEN(@products))
END
ELSE
BEGIN
SET @individual = @products
SET @products = NULL
SELECT @individual
END
END
How to parse a string with multiple underscores and dashes
Another option is a little XML
Not clear if you want a comma delimited string or separate columns
Example
Declare @YourTable Table ([ID] varchar(50),[SomeCol] varchar(150))
Insert Into @YourTable Values
(1,'Automation_LOY_Loyalty_PC_CampaignName3-Abandoners-Email1_NoPromo_USA')
,(2,'20200601_LOY_Functional_PC_CampaignName1_NoPromo_CAN')
Select A.ID
,B.Pos1
,B.Pos2
,B.Pos3
,B.Pos4
,Pos5a = xmlData.value('/x[1]','varchar(max)')
,Pos5b = xmlData.value('/x[2]','varchar(max)')
,Pos5c = xmlData.value('/x[3]','varchar(max)')
,B.Pos6
,B.Pos7
From @YourTable A
Cross Apply (
Select Pos1 = xDim.value('/x[1]','varchar(max)')
,Pos2 = xDim.value('/x[2]','varchar(max)')
,Pos3 = xDim.value('/x[3]','varchar(max)')
,Pos4 = xDim.value('/x[4]','varchar(max)')
,Pos5 = xDim.value('/x[5]','varchar(max)')
,Pos6 = xDim.value('/x[6]','varchar(max)')
,Pos7 = xDim.value('/x[7]','varchar(max)')
From ( values (cast('<x>' + replace((Select replace(SomeCol,'_','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml))) A(xDim)
) B
Cross Apply ( values (cast('<x>' + replace((Select replace(Pos5,'-','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) ) ) C(xmlData)
Returns
Parse from string specific values in SQL Server
You should use substring
SELECT SUBSTRING('w3resource',4,3);
will out put eso
4,3 means start from 4th position till next 3 characters
so in your case it will be
SELECT SUBSTRING(column_name,67,4);
This is all about MYSQL but MS SQL has the same function
SUBSTRING( string, start_position, length )
Please check this link
http://social.technet.microsoft.com/wiki/contents/articles/17948.t-sql-right-left-substring-and-charindex-functions.aspx
Parse string as JSON with Snowflake SQL
Replace only one occurrence with regexp_replace()
:
with data as (
select '---\nfield_one: 1\nfield_two: 20\nfield_three: 4\nid: 1234\nanother_id: 5678\nsome_text: Hey you\na_date: 2022-11-29\nutc: this_utc\nanother_date: 2022-11-30\nutc: another_utc' o
)
select parse_json(last2)
from (
select o,
replace(o, '---\n', '{"') || '"}' as first,
replace(first, '\n', '","') as second_,
replace(second_, ': ', '":"') as third,
replace(third, ' ', '') as fourth,
replace(fourth, ' ', '') as last,
regexp_replace(last, '"utc"', '"utc2"', 1, 2) last2
from data
)
;
Parsing a string SQL
declare @s varchar(max) = 'I=940;A=29.5;D=20090901|I=941;A=62.54;D=20090910|I=942;A=58.99;D=20091005|I=954;A=93.45;D=20091201|I=944;A=96.76;D=20091101|I=946;A=52.5;D=20091101|I=943;A=28.32;D=20091101|I=945;A=52.5;D=20091101|I=955;A=79.81;D=20091201|I=950;A=25.2;D=20091124|I=948;A=31.86;D=20091110|I=949;A=28.32;D=20091120|I=947;A=25.2;D=20091109|I=951;A=242.54;D=20091124|I=952;A=28.32;D=20091129|I=956;A=38.94;D=20091210|I=957;A=107.39;D=20091215|I=958;A=32.55;D=20091228|I=959;A=27.3;D=20091228|I=960;A=24.79;D=20091230|I=1117;A=28.32;D=20100131|I=1115;A=272.58;D=20100131|I=1116;A=159.6;D=20100209'
declare @xml xml
select @xml = '<item><value>'+replace(replace(@s, ';','</value><value>'), '|','</value></item><item><value>')+'</value></item>'
select N.value('substring(value[1],3)', 'int') as Invoice,
N.value('substring(value[2],3)', 'money') as Amount,
N.value('substring(value[3],3)', 'date') as [Date]
from @xml.nodes('item') as T(N)
Result:
Invoice Amount Date
----------- --------------------- ----------
940 29,50 2009-09-01
941 62,54 2009-09-10
942 58,99 2009-10-05
954 93,45 2009-12-01
944 96,76 2009-11-01
946 52,50 2009-11-01
943 28,32 2009-11-01
945 52,50 2009-11-01
955 79,81 2009-12-01
950 25,20 2009-11-24
948 31,86 2009-11-10
949 28,32 2009-11-20
947 25,20 2009-11-09
951 242,54 2009-11-24
952 28,32 2009-11-29
956 38,94 2009-12-10
957 107,39 2009-12-15
958 32,55 2009-12-28
959 27,30 2009-12-28
960 24,79 2009-12-30
1117 28,32 2010-01-31
1115 272,58 2010-01-31
1116 159,60 2010-02-09
For SQL Server 2005 you need to use datetime instead of date
select N.value('substring(value[1],3)', 'int') as Invoice,
N.value('substring(value[2],3)', 'money') as Amount,
N.value('substring(value[3],3)', 'datetime') as [Date]
from @xml.nodes('item') as T(N)
To read from a table you need to do it like this.
declare @s varchar(max) = 'I=940;A=29.5;D=20090901|I=941;A=62.54;D=20090910|I=942;A=58.99;D=20091005|I=954;A=93.45;D=20091201|I=944;A=96.76;D=20091101|I=946;A=52.5;D=20091101|I=943;A=28.32;D=20091101|I=945;A=52.5;D=20091101|I=955;A=79.81;D=20091201|I=950;A=25.2;D=20091124|I=948;A=31.86;D=20091110|I=949;A=28.32;D=20091120|I=947;A=25.2;D=20091109|I=951;A=242.54;D=20091124|I=952;A=28.32;D=20091129|I=956;A=38.94;D=20091210|I=957;A=107.39;D=20091215|I=958;A=32.55;D=20091228|I=959;A=27.3;D=20091228|I=960;A=24.79;D=20091230|I=1117;A=28.32;D=20100131|I=1115;A=272.58;D=20100131|I=1116;A=159.6;D=20100209'
declare @YourTable table(ID int, s varchar(max))
insert into @YourTable values
(1, @s),
(2, @s)
select Y.ID,
T.N.value('substring(value[1],3)', 'int') as Invoice,
T.N.value('substring(value[2],3)', 'money') as Amount,
T.N.value('substring(value[3],3)', 'date') as [Date]
from @YourTable as Y
cross apply (select cast('<item><value>'+replace(replace(Y.s, ';','</value><value>'), '|','</value></item><item><value>')+'</value></item>' as xml)) as X(XMLCol)
cross apply X.XMLCol.nodes('item') as T(N)
Parsing a string in postgresql
We can use REGEXP_REPLACE
here:
SELECT col, REGEXP_REPLACE(col, '.*\[\w+ UID=(\d+)\].*$', '\1') AS uid
FROM yourTable;
Demo
Edit:
In case a given value might not match the above pattern, in which case you would want to return the entire original value, we can use a CASE
expression:
SELECT col,
CASE WHEN col LIKE '%[%UID=%]%'
THEN REGEXP_REPLACE(col, '.*\[\w+ UID=(\d+)\].*$', '\1')
ELSE col END AS uid
FROM yourTable;
How to parse SQL Server String in hour, min and second
You can also create a function to perform the conversion with basic text manipulation:
CREATE FUNCTION dbo.f_GetTime(@TimeInput VARCHAR(50)) RETURNS TIME
AS BEGIN
SET @TimeInput = REPLACE(REPLACE(@TimeInput, 'PT', ''), 'S', '')
IF CHARINDEX('H', @TimeInput) = 0 -- Add missing H
SET @TimeInput = '0H' + @TimeInput
IF CHARINDEX('M', @TimeInput) = 0 -- Add missing M
SET @TimeInput = REPLACE(@TimeInput, 'H', 'H0M')
RETURN CONVERT(TIME, REPLACE(REPLACE(@TimeInput, 'H', ':'), 'M', ':'))
END
GO
Then you can use it with just scalar queries:
SELECT dbo.f_GetTime('PT1H22M59.551S') AS TimeValue
Or you can use it with tables:
DECLARE @Input TABLE (TimeInput VARCHAR(20))
INSERT @Input VALUES ('PT1H22M59.551S'), ('PT0S'), ('PT6H4M29.212S'), ('PT0S'),
('PT2M55.126S'), ('PT54M4.12S'), ('PT3H6M5.74S'), ('PT16H27M52.069S')
SELECT TimeInput, dbo.f_GetTime(TimeInput) AS TimeValue FROM @Input
This would return:
TimeInput TimeValue
-------------------- ----------------
PT1H22M59.551S 01:22:59.5510000
PT0S 00:00:00.0000000
PT6H4M29.212S 06:04:29.2120000
PT0S 00:00:00.0000000
PT2M55.126S 00:02:55.1260000
PT54M4.12S 00:54:04.1200000
PT3H6M5.74S 03:06:05.7400000
PT16H27M52.069S 16:27:52.0690000
Related Topics
Sql Date Format Conversion from Int(Yyyymmdd) Type to Date(Mm/Dd/Yyyy)
Issue of Multiple SQL Notifications in ASP.NET Web Application on Page Refresh
Sql Query - Limiting Query Results
Sql Select Distinct Substring Where Like Muddleup Howto
How to Add a Running Count to Rows in a 'streak' of Consecutive Days
Row Locks - Manually Using Them
Trying to Connect to an Odbc Server Using Rodbc in Ubuntu
How to Analyze 'Dbcc Memorystatus' Result in SQL Server 2008
Sql Server 2000 - Query a Table's Foreign Key Relationships
Kill All User Connections in SQL Azure
How to Insert Distinct Records from Table a to Table B (Both Tables Have Same Structure)
What Is Wrong with My Update Statement with a Join in Oracle
How to Change Default Systemdate from Ymd to Dmy
Presto Sql: Changing Time Zones Using Time Zone String Coming as a Result of a Query Is Not Working