substring to retrieve a date between two characters - sql-server

Could someone shed some light on how I could extract the date field from this string below
'NA,Planning-Completed=17-07-2019 10:38,Print-Dispatch-Date=10-02-2020 13:06,Award-Complete=NA'
Expected Output:
10-02-2020
This is what I have written so far, it seems to work sometimes but I noticed some rows are incorrect.
[Dispatch Date] = SUBSTRING(dates,CHARINDEX('Print-Dispatch-Date=',dates) + LEN('Print-Dispatch-Date='), LEN(dates) )

The 3rd parameter for SUBSTRING is wrong. You have it as LEN(dates), which means return every character after 'Print-Dispatch-Date='; in this case that returns '10-02-2020 13:06,Award-Complete=NA'.
As your date is 10 characters long, just use 10:
SELECT dates, SUBSTRING(dates,CHARINDEX('Print-Dispatch-Date=',dates) + LEN('Print-Dispatch-Date='), 10)
FROM (VALUES('NA,Planning-Completed=17-07-2019 10:38,Print-Dispatch-Date=10-02-2020 13:06,Award-Complete=NA'))V(dates)

Related

T-SQL: SUM Number between Delimiters from String

I need to get numbers with a variable length out of a string and sum them.
The strings got the following format:
EH:NUMBER=SomeOtherStuff->Code
I'm extracting the code via RIGHT() and join with another table to get the group right, at the moment I'm using sum to get it together via date:
SUM(CASE WHEN (MONTH(data.DATE1) = 5 AND YEAR(data.DATE1) = YEAR(GETDATE())) THEN 1 ELSE 0 END) N'Mai',
I then need to sum the numbers from the string and not the number of rows.
Some Examples:
Month1 EH:1=24->ZTM
Month1 EH:4=13-21->LKm
Month2 EH:3=34,33,43->LKm
Month2 EH:7=12,92-29,29->LKm
Month2 EH:5=24-26,11,21,22->ZOL
What i need:
Material - Month1 - Month2
ZTM - 1 - 0
LKM - 4 - 10
ZOL - 0 - 5
Could you help me please?
Greetings
Short version:
What you are looking for is SUBSTRING.
Longer version:
To get the the sum of the numerical value of NUMBER you need think about how break it down.
I'd recommend following these steps:
Extract the NUMBER part from the string. This should be done with SUBSTRING (much like you extract Code with RIGHT). To get the start and and length och your substring use charindex ( or patindex if you like).
Convert the NUMBER part to a numerical value with cast (or convert or what you are familiar with)
Now you can do your aggregation.
So SUM(CAST(SUBSTRING(*this part you will have to figure out by yourself)) as correct numerical data type)).
I'll let you figure out the values to insert by yourself and would recommend to first find the positions of the delimiting characters, then extract the NUMBER part, then get the numerical value .... you get it .
This to gain a better understanding of what you are actually doing.
Cheers, and good luck with your assignment
Martin

SQL Server - How to get last numeric value in the given string

I am trying to get last numeric part in the given string.
For Example, below are the given strings and the result should be last numeric part only
SB124197 --> 124197
287276ACBX92 --> 92
R009321743-16 --> 16
How to achieve this functionality. Please help.
Try this:
select right(#str, patindex('%[^0-9]%',reverse(#str)) - 1)
Explanation:
Using PATINDEX with '%[^0-9]%' as a search pattern you get the starting position of the first occurrence of a character that is not a number.
Using REVERSE you get the position of the first non numeric character starting from the back of the string.
Edit:
To handle the case of strings not containing non numeric characters you can use:
select case
when patindex(#str, '%[^0-9]%') = 0 then #str
else right(#str, patindex('%[^0-9]%',reverse(#str)) - 1)
end
If your data always contains at least one non-numeric character then you can use the first query, otherwise use the second one.
Actual query:
So, if your table is something like this:
mycol
--------------
SB124197
287276ACBX92
R009321743-16
123456
then you can use the following query (works in SQL Server 2012+):
select iif(x.i = 0, mycol, right(mycol, x.i - 1))
from mytable
cross apply (select patindex('%[^0-9]%', reverse(mycol) )) as x(i)
Output:
mynum
------
124197
92
16
123456
Demo here
Here is one way using Patindex
SELECT RIGHT(strg, COALESCE(NULLIF(Patindex('%[^0-9]%', Reverse(strg)), 0) - 1, Len(strg)))
FROM (VALUES ('SB124197'),
('287276ACBX92'),
('R009321743-16')) tc (strg)
After reversing the string, we are finding the position of first non numeric character and extracting the data from that position till the end..
Result :
-----
124197
92
16

SQL Select statement until a character

I'm looking to extract all the text up until a '\' (backslash).
The substring is required to remove all proceeding characters (17 in total) and so I would like to return all after the 17th until it comes across a backslash.
I've tried using charindex but it doesn't seem to stop at the \ it returns characters afterward. My code is as follows
SELECT path, substring(path,17, CHARINDEX('\',Path)+ LEN(Path)) As Data
FROM [Table].[dbo].[Projects]
WHERE Path like '\ENQ%\' AND
Deleted = '0'
Example
The below screen shot shows the basic query and result i.e the whole string
I then use substring to remove the first X characters as there will always be the same amount of proceeding characters
But what Im actually after is (based on the above result) the "Testing 1" "Testing 2" and "Testing ABC" section
The substring is required to remove all proceeding characters (17 in total) and so I would like to return all after the 17th until it comes across a backslash.
select
substring(path,17,CHARINDEX('\',Path)-17)
from
table
To overcome Invalid length parameter passed to the LEFT or SUBSTRING function error, you can use CASE
select
substring(path,17,
CASE when CHARINDEX('\',Path,17)>0
Then CHARINDEX('\',Path)-17)
else VA end
)
from
table

SQL Server: substring leading zero counting is off

I'm trying to make 3 separate fields from a date and now I ran into this problem. When the (DDMMYYYY European style) date is like 04032017, the code:
SELECT SUBSTRING(CAST(04032017 AS VARCHAR(38)), 2, 2) AS Month
returns 03 (perfect).
But when the code is like (the first zero is now a 1!) :
SELECT SUBSTRING(CAST(18022017 AS VARCHAR(38)), 2, 2) AS Month
the result is 80 because SUBSTRING now is counting from the (1) first position and in the first example it took 4 as the starting point.
Obviously I need to have 1 code for all occurrences but I just don't get it right.
Some help would be appreciated!
Regards, J
This should work for you:
select SUBSTRING(right('00000000' + CAST(04032017 AS varchar(38)),8), 3, 2) as Month
You might require to parse this as varchar and then convert into valid date and use month() function to get clear approach
declare #date nvarchar(10)='18022017'
select Month(cast(CONCAT(SUBSTRING(#date,3,2),'/',SUBSTRING(#date,1,2),'/',SUBSTRING(#date,5,4)) as date))
Ok, just solved it. Just remove the cast (why did I use that in the first place?) and put single quotes around the date:
select SUBSTRING('04032017'), 2, 2) as Month
This works just fine!

Converting text to Datetime in specific format

I need an expression which will convert a text (VARCHAR) column to a DATETIME if, and only if, it matches dd/MM/yyyy, d/MM/yyyy, dd/M/yyyy or d/M/yyyy. If it doesn't match then I want a NULL.
I have this...
CASE ISDATE([DateField])
WHEN 1 THEN CONVERT(DATETIME,[DateField],103)
ELSE NULL
END
However this fails for '15/04/76' for example - with a "Conversion failed when converting datetime from character string" error - whereas I would want it to return NULL
Example output
'1/6/1976' -> 1976-06-01
'01/06/1976' -> 1976-06-01
'13/06/2001' -> 2001-06-13
'06/13/2001' -> NULL
'13/06/76' -> NULL
Is there a way of forcing ISDATE to validate a given format?
The documentation seems to suggest so...
ISDATE is deterministic only if used with the CONVERT function, the
CONVERT style parameter is specified and style is not equal to 0, 100,
9, or 109.
But ISDATE only takes one argument, so how do I "use it with CONVERT function" if I am not doing so already?
You could do a nested case statement here. The first could check to see if you have a 10 character string 2 for day, 2 for month, 4 for year and 2 for separators = 10 characters.
SET DATEFORMAT DMY;
Case When DateField Like '%/%/[0-9][0-9][0-9][0-9]'
Then Case When IsDate(DateField) = 1
Then CONVERT(DATETIME,[DateField],103)
End
End
Revised: I changed the code to use a like search which forces there to be a /YYYY at the end of the string, and then does an IsDate check to allow for a single day and/or month.
Well, first off, why on earth are you storing datetime values in a varchar column? This is a cardinal sin for a variety of reasons, not the least of which is that you get no validation whatsoever that the data is (or is convertible to) a datetime. You should also consider validating the input, even if you leave the column as varchar, so you don't have such a wide variety of potential formats that you want to consider valid.
So here is one way, borrowing a bit from #G Mastros:
DECLARE #f TABLE(i INT, d VARCHAR(32));
INSERT #f VALUES
(1,'15/04/76'),
(2,'15/04/1976'),
(3,'1/3/1976'),
(4,'1/3/76'),
(5,'15/3/1976'),
(6,'22/22/22'),
(7,'Yesterday');
SET DATEFORMAT DMY;
SELECT i, d, d2 = CASE WHEN ISDATE(d) = 1
AND d LIKE '%/[0-9][0-9][0-9][0-9]'
THEN CONVERT(DATETIME, d, 103) END
FROM #f;
Results:
i d d2
- ---------- -----------------------
1 15/04/76 NULL
2 15/04/1976 1976-04-15 00:00:00.000
3 1/3/1976 1976-03-01 00:00:00.000
4 1/3/76 NULL
5 15/3/1976 1976-03-15 00:00:00.000
6 22/22/22 NULL
7 Yesterday NULL
PS this will be a great case for TRY_CONVERT in SQL Server 2012. It does exactly what you're asking - it tries to convert to the specified data type; if it can't, it returns NULL.
Thanks for the responses folks.
I've done it like this...
CASE ISDATE([DateField]) WHEN 1 THEN
CASE WHEN SUBSTRING([DateField],LEN([DateField])-4,1) = '/' THEN
CASE WHEN CHARINDEX('/',[DateField],LEN([DateField])-3)=0 THEN
CONVERT(datetime, [DateField] , 103)
END
END
END
which is pretty nasty business so would still appreciate something neater!
But this doesn't work either - it still errors on mm/dd/yyyy format dates!
Scrap that last comment - it does seem to work now? Probably something to do with SET DATEFORMAT

Resources