I m currently working on a SQl in MS-Access 2010 that can split a column based on a delimiter(,). In the column where I want to split on can have zero, one, two or three delimiter. I found out how i can split the column if there is only one delimiter (see SQL at the end of the question) but not if there are multiple delimiters.
The SQL is based on the following table. This table is filled with possible data that can occur in the table.
ID column_value
---------------------
1 2, 44
2 1
3 8, 9, 4
4 7
I want to split the column "value" in a way that i create a new table like this. It is not a problem that the column "ID" is the same because this will not be the PK.
ID value
---------------------
1 2
1 44
2 1
3 8
3 9
3 4
4 7
I tried to alter the SQL from this question but it only works when there is only 1 delimiter(,) due to the fact is uses the function LEFT and MID. I cant find how to alter it in a way that i can split if there are more then 1 delimiter in the column. The SQL i used to split if there is one delimiter:
select * into importeddata
from (SELECT column_value, id
FROM SourceData
WHERE InStr(column_value, ',') = 1
UNION ALL
SELECT Left(column_value, InStr(column_value, ',') - 1), id
FROM SourceData
WHERE InStr(column_value, ',') > 0
UNION ALL
SELECT mid(column_value, InStr(column_value, ',')+1 ), id
FROM SourceData
WHERE InStr(column_value, ',') > 0) AS CleanedUp;
Does somebody knows how to split a column if there is more then one delimiter?
To split and obtain a specific value, I prefer to use a user-defined function.
Public Function SplitString(str As String, delimiter As String, count As Integer) As String
Dim strArr() As String
strArr = Split(str, delimiter, count + 1)
count = count - 1 'zero-based
If UBound(strArr) >= count Then
SplitString = strArr(count)
End If
End Function
After this, you can adjust your SQL to the following:
SELECT * INTO importeddata
FROM (
SELECT SplitString(column_value, ',', 1), id
FROM SourceData
WHERE SplitString(column_value, ',', 1) <> ''
UNION ALL
SELECT SplitString(column_value, ',', 2), id
FROM SourceData
WHERE SplitString(column_value, ',', 2) <> ''
UNION ALL
SELECT SplitString(column_value, ',', 3), id
FROM SourceData
WHERE SplitString(column_value, ',', 3) <> ''
) AS A
If you really want an all-SQL solution, let me demonstrate to you how this can be achieved, and why this is a bad plan.
For this example, I've written the following code to automatically generate the appropriate SQL expression
Public Sub GenerateSQLSplit(str As String, Delimiter As String, Count As Integer)
Dim i As Integer
If Count = 1 Then
Debug.Print "IIf(InStr(1, " & str & ", " & Delimiter & ") = -1, " & str & ", Left(" & str & ", InStr(1, " & str & ", " & Delimiter & ") - 1))"
Else
Dim strPrevious As String
Dim strNext As String
strPrevious = "InStr(1, " & str & "," & Delimiter & ")"
i = Count - 1
Do While i <> 1
strPrevious = "InStr(" & strPrevious & " + Len(" & Delimiter & "), " & str & "," & Delimiter & ")"
i = i - 1
Loop
strNext = "InStr(" & strPrevious & " + Len(" & Delimiter & "), " & str & " , " & Delimiter & ")"
Debug.Print "IIf( " & strPrevious & "> 0, IIf(" & strNext & " < 1, Mid(" & str & ", " & strPrevious & " + Len(" & Delimiter & ")), Mid(" & str & ", " & strPrevious & " + Len(" & Delimiter & "), " & strNext & " - " & strPrevious & " - Len(" & Delimiter & "))), """") "
End If
End Sub
Let's use the example to generate a simple split: I want the 6th element of the following string: 1,2,3,4,5,6,7
To generate the string, in the immediate window:
GenerateSQLSplit "'1,2,3,4,5,6,7'", "','", 6
Results in the following expression to return the 6th element of that string (SQL only):
IIf( InStr(InStr(InStr(InStr(InStr(1, '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',')> 0, IIf(InStr(InStr(InStr(InStr(InStr(InStr(1, '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7' , ',') < 1, Mid('1,2,3,4,5,6,7', InStr(InStr(InStr(InStr(InStr(1, '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(',')), Mid('1,2,3,4,5,6,7', InStr(InStr(InStr(InStr(InStr(1, '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), InStr(InStr(InStr(InStr(InStr(InStr(1, '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7'
,',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7' , ',') - InStr(InStr(InStr(InStr(InStr(1, '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') + Len(','), '1,2,3,4,5,6,7',',') - Len(','))), "")
Append SELECT to the start of that, and execute it as a query, and it returns 6, as expected. Only you have a totally horrid query, while with the UDF you would just have SELECT SplitString("1,2,3,4,5,6,7", ",", 6)
You can, of course, use GenerateSQLSplit to create the query (I made sure it returned an empty string if the item was not in the string, so you can use that to test if an nth element exists). I do not recommend it, though, because the query will be long, inefficient and hard to maintain.
I am making a small program and it uses WMI. There is a value which is, supposedly, a date and time. The value appears to be:
"20140221163958.621000+330".
Can anyone tell me which format is this and how to convert this to normal readable DateAndTime.
This is the official TechNet article regarding the timestamp format for WMI queries:
http://technet.microsoft.com/en-us/library/ee156576.aspx
Witch as it so happens gives a nice example in VB:
dtmInstallDate = "20140221163958.621000+330"
WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _
Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _
& " " & Mid (dtmInstallDate, 9, 2) & ":" & _
Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _
13, 2))
' would produce "2/21/14 4:39:58 PM"
A quick search showed that it is the Standard Windows Format (UTC) (http://msdn.microsoft.com/en-us/library/aa394370(v=vs.85).aspx for more reference). To Convert it, I used a simple function.
Private Function ConvertToDateTime(ByVal in As String) As String
Return CDate(Mid(inDate, 5, 2) & "/" & _
Mid(inDate, 7, 2) & "/" & Left(inDate, 4) _
& " " & Mid(inDate, 9, 2) & ":" & _
Mid(inDate, 11, 2) & ":" & Mid(inDate, _
13, 2))
End Function
http://technet.microsoft.com/en-us/library/ee156576.aspx
you can try this way
SELECT
SUBSTRING(date, 1, 4) as year,SUBSTRING(date, 5, 2) as month,
SUBSTRING(date, 7, 2) as day,SUBSTRING(date, 9, 2) as hours,
SUBSTRING(date, 11, 2) as minutes,SUBSTRING(date, 13, 2) as seconds
FROM
table1
DEMO HERE
if you want update your table and change this column use this
Update table1 set date =
concat(SUBSTRING(date, 1, 4),' ',SUBSTRING(date, 5, 2),' ',
SUBSTRING(date, 7, 2),' ',SUBSTRING(date, 9, 2),':',
SUBSTRING(date, 11, 2),':',SUBSTRING(date, 13, 2))
demo