Select a date in a string and convert it to datetime - sql

I have a string like:
'SPY US 03/20/20 P45'
I want to select just the date from the string.
My current query is:
Select Ticker, SUBSTRING(Ticker, PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9]%',o.Ticker),8) AS 'myDate' FROM TABLE
This returns: 'SPY US 03/20/20 P45', 03/20/20
I want myDate to be in datetime.
I have tried various morphs of cast and convert, but they fail, presumably because they want the format to be in YYYY-MM-DD rather than MM/DD/YY.
My "smartest" attempt to convert was this:
CONVERT(DATETIME, SUBSTRING(o.Ticker, PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9]%',o.Ticker),8),1)
After reading style guidelines here: https://www.w3schools.com/sql/func_sqlserver_convert.asp
but it still failed.
The ideal end-format for the date would be YYYY-MM-DD
Edited to add:
I have been fiddling with it and realized that I over simplied my question. The convert works if I just test it on a string, but the entire query involves several joins.

As I can understand you are looking for something like this.
You can use string_split() function to split string with blank space and then use try_cast() function to check each value whether it is a date.
declare #string as varchar(120) = 'SPY US 03/20/20 P4'
; with cte as (select
value
from string_split (#string, ' ')
)Select value from cte where try_cast (value as datetime) is not null
Live db<>fiddle demo.

So it turns out that there were a few entries in the column that didn't have friendly date format, so the patindex clause was returning nonsense.
For some reason that caused the entire operation to fail(rather than just returning null on the few entries that were failing).
Once I selected the entire (ultimately more complicated join statement) into a temp table, then I was able to try_convert the substring into a date and run my operations.

Related

Convert from varchar into date in SQL Server

This looks easy solution but I can't seem to figure out as to why this is not working for me. I have a column that has data like this:
DateField
----------
12/16/2016
11/06/2016
All I want to do is to convert from varchar into a date column, but I am getting this error:
Conversion failed when converting date and/or time from character string.
Here is my simple query:
select convert (date, DateField) as convertedField
from myTable
Nothing wrong with the two examples you have given. There are some bad dates in your table which cannot be converted to date.
Use TRY_CONVERT function for bad dates it will return NULL
select TRY_Convert(date,DateField)
From myTable
You should always store dates in DATE/DATETIME datatype.
If you want to see the records which cannot be converted to date then
select DateField
From myTable
Where TRY_Convert(date,DateField) IS NULL
If working with a specific date format like mm/dd/yyyy You can specify it in Convert() function like the following
CONVERT(DATETIME,DATAFIELD,101)
If it still is not working, use TRY_CONVERT() to get which rows are throwing this exception:
SELECT *
FROM TBL
WHERE TRY_CONVERT(DATETIME, DATAFIELD, 101) IS NULL
This will return rows that cannot be converted
TRY_CONVERT() will return NULL if conversion failed
Read more about DateTime formats here:
SQL Server CONVERT() Function tutorial
Read TRY_CONVERT MSDN Article
You need to specify the format of date time while formatting. The date in your table is currently in U.S format so you should pass the third argument 101 in your convert function.
SELECT CONVERT(date,[DateField],101) FROM myTable;
Working Fiddle here http://rextester.com/NYKR49788
More info about date time style here: https://msdn.microsoft.com/en-us/library/ms187928.aspx

How can I format a datetime in SQL Server R2 to dd-MMM-yy (or dd-mon-yy)?

Sample input: 2014-03-28 00:00:00.000
Sample output: 28-Mar-14
Current SQL:
SELECT StartDate
FROM myTable
Surprisingly, I could not find this particular format on StackOverflow for SQL Server so I thought I should add it to help save the next person some time.
Try this :-
SELECT REPLACE(CONVERT(VARCHAR,GETDATE(),6),' ','-')
Your query will be :-
SELECT REPLACE(CONVERT(VARCHAR,StartDate,6),' ','-') AS StartDate FROM myTable
New SQL:
SELECT REPLACE(CONVERT(CHAR(9), StartDate, 6),' ','-') AS FormattedStartDate
FROM myTable
Here's how it works in case you need to adjust for your needs:
CONVERT(CHAR(9), StartDate, 6) will output a CHAR(9). Make sure this is long enough for your desired output.
The value of 6 in the 3rd parameter tells CONVERT to output in the format
dd mon yy.
Notice that format has spaces which is why you need the REPLACE function if you want hyphens (-), slashes (/), or whatever instead of those spaces.
NOTE: If the date field is usually not null, CHAR(9) will use fewer bytes than VARCHAR. If there are a lot of blank data in the field, I would consider replacing the CHAR(9) with a VARCHAR because it will output fewer bytes in that case.

Why my selection between two dates in the same table doesn't work?

I use SQL server 2014, i try the following query to select between two dates in the same table, the datatype is nvarchar, i executed the following query it just shows me three rows such('30/03/2015','30/04/2015','30/04/2015'),but in reality there is('29/02/2015','30/03/2015','31/04/2015','30/04/2015','30/04/2015')
select RegisteredDate
from Student
where Student.RegisteredDate between convert(nvarchar, '30/01/2014', 103)
and convert(nvarchar, '30/04/2015', 103)
Cast the other way round, other way you are comparing strings:
select RegisteredDate from Student
where convert(date, Student.RegisteredDate, 103) between '20140130' and '20150430'
The fact is that those dates saved as strings are ordered as:
'29/02/2015',
'30/03/2015',
'30/04/2015',
'30/04/2015',
'31/04/2015'
Now imagine where would you add filter values?
'29/02/2015',
'30/01/2014' --start date
/-------------\
|'30/03/2015',|
|'30/04/2015',|
|'30/04/2015',|
\-------------/
'30/04/2015' --end date
'31/04/2015'
So between will return you those three rows.
Also you have in your data 29/02/2015. In 2015 February ends on 28(you have incorrect data in tables already). You will never be able to insert such values if you choose types correctly.So the conclusion is:
Use Appropriate data types for your data!
As i have read the other answers and comments, i could recommend you to firstly change the datatype of "RegisteredDate" from "nvarchar" to "date". Secondly use this standard 'yyyy-MM-dd' below code is what you need
select RegisteredDate
from Student
where Student.RegisteredDate between '2014-01-30' and '2015-04-30'
you will not be in need of any conversions, this is how i do it for myself
Try to cast your string to date instead of casting all the dates in the table to string.
You are casting all the records in the table to string and it might be millions of them. This way not only your performance will be better but more important you will compare them to dates, not as String.
SELECT RegisteredDate
FROM Student
WHERE Student.RegisteredDate BETWEEN Convert(Date, '30/01/2014',103) AND Convert(Date, '30/04/2015', 103)
As I said in the comments, a string comparation uses alphabetical order one char after another starting from the left. For example: 20/01/1302 will be after 01/12/4016 as the "2" char goes after the "1" char in ASCII.
Update: convert Student.RegisteredDate to date if it is still in nvarchar type. I would recommend you to change the type if you can to this. It might be a source of bugs and performance problems if you do not do this.
SQL Server 2014 makes the string to dates conversion automagically but only if it needs to. Comparing a '30/04/2015' string with a nvarchar is just a String comparation.

regular expression not working on the datetime column

The date in my table looks like 2010-06-16 00:00:00.000
When I use the below regular expression, no rows get selected.
select mydate from mytable where mydate like '2010%'
However, when I use this one, rows do get selected correctly.
select mydate from mytable where mydate like '%2010%'
So, I thought that probably leading white spaces are getting added. To take those into account, I used the below query. But this doesn't work either.
select mydate from mytable where LTRIM(RTRIM(mydate)) like '2010%'
Since the first one works, it means, that there is something before the 2010? What else apart from white spaces, could it be? I tried pasting it onto a text file, and don't see anything.
If the datatype is Datetime you should use Year() function to filter the rows instead of like. You should not use like operator to filter the data from Datetime type.
If the datatype is Datetime then you won't be having leading or trailing spaces.
You do have appropriate Date functions in Sql Server use those to filter the rows.
select mydate from mytable where year(mydate) = 2010
or even Datepart
select mydate from mytable where Datepart(YYYY,mydate) = 2010
You have to convert datetime that first in varchar to use like
select mydate from mytable
WHERE CONVERT(VARCHAR(10),mydate,120) like '2010%'
DEMO
You probably should use just date range fetches, for example
select mydate from mytable where mydate >= '20100101' and mydate < '20110101'
Using functions for the column (e.g. year(mydate)) is not a good idea because then indexes can't be used. Using 'between' can also cause problems with datetime columns because the time part can cause you to accidentally leave out rows.
The reason you found something with your search is probably due to typecasting the date into varchar before comparison, and format is such that the year is at the end, but please don't use that.

Like operator in Datetime column

I want to use Like operator in a column of datetime. The values of the column is as follows:
2013-08-31 17:54:52.000
2013-08-31 17:54:52.000
My query is as below:
SELECT * FROM table where created_date Like '%54%'
It works fine. but when I search for '%52%' instead of '%54%', it gives me nothing. (It is working when I search till the minutes, but when I search for seconds or milli seconds it does not work.)
I have looked at the following url and it is working
SQL LIKE Statement on a DateTime Type
I want to know the reason, why this is happening and how like operator works with datetime type column.
I think it would be a better idea to use the DATEPART operator of SQL SERVER to extract the portion of date.
And example could be like:-
SELECT * FROM table
where DATEPART(minute,created_date)=54
EDIT:-
I want to know the reason, why this is happening and how like operator
works with datetime type column.
Actually there is no direct support given by SQL Server for LIKE operator for DATETIME variable but you can always cast the DATETIME to a VARCHAR and then try to use the LIKE operator as you want.
On a side note:-
MSDN says:-
DATEPART can be used in the select list, WHERE, HAVING, GROUP BY and
ORDER BY clauses.
In SQL Server 2012, DATEPART implicitly casts string literals as a
datetime2 type. This means that DATEPART does not support the format
YDM when the date is passed as a string. You must explicitly cast the
string to a datetime or smalldatetime type to use the YDM format.
The 'LIKE' operator and any regular expression operators provided by other databases are used to process text values. A date is definitely not a text value, it is a separata type by itself.
It makes little sense to apply a text operator to a non-text type (like int or DATETIME or DATETIMEOFFSET), which is why you can't use LIKE on dates in any database. First of all, the values are not stored as text but in an implementation-specific binary form.
Then, while you can use LIKE on a specific text representation of a date, eg using CAST you have to absolutely certain what that representation is. Different locales display dates differently, with year first, year last, month first or last or whatever. What would you search against?
Moreover, what is 54? 54 minutes, 54 seconds or 654 milliseconds?
The only sensible solution is to use DATEPART to check specific parts of a date, or the BETWEEN operator to check for ranges.