I have a string field in database named "ExamDate" which contains dates. Initially, the application had no front-end validation in place and database was saving as string, so users were able to input dates in any format.
The required format is DD-MMM-YYYY but currently the field has values in all formats, like:
14-Jun-2017
9/15/2017
May 2017
February 1, 2017
NULL value
I have to display this field in a DB view and convert all of them into date format.
The various options I tried give me errors like:
"a non-numeric character was found where a numeric was expected" or
"invalid number"
I also realized that the "day" field is missing in a few of the dates, like 'May 2017' which needs to be set to 01-May-2017.
Do you suggest going ahead with a solution similar to one pasted below from path: How to update dates stored as varying character formats (PL/SQL)?
SELECT ANTICIPATEDSPUD
,DECODE (
INSTR (ANTICIPATEDSPUD, '-')
,5, TO_DATE (ANTICIPATEDSPUD, 'YYYY-MM-DD')
,3, TO_DATE (ANTICIPATEDSPUD, 'MM-DD-YYYY')
,DECODE (LENGTH (ANTICIPATEDSPUD)
,8, TO_DATE (ANTICIPATEDSPUD, 'MM/DD/YY')
,10, TO_DATE (ANTICIPATEDSPUD, 'MM/DD/YYYY')))
FROM FSW_BASIC_WELL_INFO_VW;
Perhaps you could try to group data that share the same format. REGEXP_LIKE might be handy in such a case. It might be OK as it allows you to "upgrade" it easily, as soon as you find yet another format people used to enter data.
The following example certainly isn't ideal because of typos; months could have been "Ferubrary" or "Mya"; days could be 35, months 13 and so forth so you'd have to check whether those values are meaningful.
Anyway; have a look. I've included the ID column just for sorting purposes.
SQL> alter session set nls_date_language = 'english';
Session altered.
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> with test (id, datum) as
2 (select 1, '14-Jun-2017' from dual union
3 select 2, '9/15/2017' from dual union
4 select 3, 'May 2017' from dual union
5 select 4, 'February 1, 2017' from dual union
6 select 5, null from dual
7 )
8 select id, datum, to_date(datum, 'dd-mon-yyyy') result from test
9 where regexp_like(datum, '[0-9]{1,2}-[[:alpha:]]{3}-[0-9]{4}')
10 union
11 select id, datum, to_date(datum, 'mm/dd/yyyy') from test
12 where regexp_like(datum, '[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}')
13 union
14 select id, datum, to_date(datum, 'mon yyyy') from test
15 where regexp_like(datum, '[[:alpha:]]{3} [0-9]{4}')
16 union
17 select id, datum, to_date(datum, 'month dd, yyyy') from test
18 where regexp_like(datum, '\w+ [0-9]{1,2}, [0-9]{4}')
19 order by id;
ID DATUM RESULT
---------- ---------------- ----------
1 14-Jun-2017 14.06.2017
2 9/15/2017 15.09.2017
3 May 2017 01.05.2017
4 February 1, 2017 01.02.2017
SQL>
Related
I used following queries to get date from one table and insert into another table.
INSERT INTO InstallmentPaymentHistory
VALUES('DateSold')
SELECT CONVERT(VARCHAR(11), s.DateSold, 113) AS DateSold
FROM SalesInvoice s
WHERE s.SalesInvoiceID = 9;
but I get an error
Conversion failed when converting date and/or time from character string
I have also tried
INSERT INTO InstallmentPaymentHistory
VALUES('YYYY.MM.DD')
SELECT CONVERT(VARCHAR(11), s.DateSold, 113) AS DateSold
FROM SalesInvoice s
WHERE s.SalesInvoiceID = 9;
But I get the same error.
Table #1
SalesInvoiceID CustomerID SoldDate TotalBill
-------------------------------------------------------
1 3840 2018.03.22 20000
2 4581 2018.04.11 80000
3 4420 2018.05.13 60000
Table # 2
InstallmentPaymentID SalesInvoiceID InstallmentNo DueDate PaymentDdate
---------------------------------------------------------------
1 2 1 2018.03.22 2018.3.22
2 2 2 2018.04.11 2018.3.22
3 2 3 2018.05.13 2018.3.22
Not entirely clear what you're trying to do with those commands......
If you want to use the SELECT, combined with some fixed values, then you should use something like this:
INSERT INTO dbo.InstallmentPaymentHistory (specify-the-list-of-columns-here!)
SELECT
-- provide the fixed values here, first
11, 9, 2, 'DateSold', '20180306', 6000,
-- then the "calculated/converted" value from your other table
CONVERT(VARCHAR(11), s.DateSold, 113)
FROM
dbo.SalesInvoice s
WHERE
s.SalesInvoiceID = 9;
Also: it's not clear from your post whether the date string 2018.3.6 refers to the 3rd of June or the 6th of March - but I'd recommend to always use the adapted ISO-8601 format, which is YYYYMMDD (without any dashes or anything!).
So for 6th of March, use 20180306, and for 3rd of June use 20180603
I just did query to find the number of months between two dates (except current month) in SQL Server:
SELECT
(DATEDIFF(MONTH, DATEADD(MONTH, 1, '2016-02-20 00:00:00.000') -
DAY(DATEADD(MONTH, 1, '2016-02-20 00:00:00.000')), '2016-12-31 00:00:00.000'))
The above will return 10 .. how do we achieve this in Oracle?
I guess - atleast in 10g and above - the correct function is
SELECT MONTHS_BETWEEN([date1],[date2]) FROM dual
Furthermore it is possible to calculate the difference between two dates
SELECT [date2] - [date1] FROM dual
This will give you the difference in days.
There are several different ways to count a difference in months;
a good starting point could be months_between:
SQL> with testDates (date1, date2) as
2 (
3 select date '2016-12-31', date '2016-02-20' from dual union all
4 select date '2016-02-01', date '2016-01-31' from dual union all
5 select date '2016-12-30', date '2016-11-30' from dual union all
6 select date '2016-12-29', date '2016-11-30' from dual
7 )
8 select date1, date2, months_between(date1, date2) diff, floor(months_between(date1, date2) ) floor_diff
9 from testDates;
DATE1 DATE2 DIFF FLOOR_DIFF
--------- --------- ---------- ----------
31-DIC-16 20-FEB-16 10,3548387 10
01-FEB-16 31-GEN-16 ,032258065 0
30-DIC-16 30-NOV-16 1 1
29-DIC-16 30-NOV-16 ,967741935 0
The Right query to find the sum of months between two dates in Oracle11g..Please try it
SELECT COUNT(0) TOTAL_MONTHS
FROM (SELECT DATE '2015-01-05' START_DATE,
DATE '2015-12-15' END_DATE
FROM DUAL)
CONNECT BY LEVEL <= MONTHS_BETWEEN(
TRUNC(END_DATE,'MM'),
TRUNC(START_DATE,'MM') )
+ 1
I am newbie on SQL Server and I am trying to figure out it. I need your help in a case.
I have table named MainTable in my database. Inside the table I have 3 Columns named Id, StartDate, EndDate.
What I want is: I want to send query a month, It will look if that month is between start date and end date. If yes It should return that line's ID.
For example:
In Line 1: Id: 12, Startdate: 2015-01-01, EndDate: 2015-06-01
In Line 2: Id: 14, Startdate: 2015-05-01, EndDate: 2015-08-01
If I make query 'March'. It should return 12
I can write months between two dates but i can not make query in it.
Can you help me?
You can type March and expect it return column id = 12
but you can type 3 and it will return the right rows
declare #MonthNum as tinyint
select id from MainTable where #MonthNum between
datepart(Month,Startdate) and datepart(Month,EndDate)
you could try this
DECLARE #MonthName VARCHAR(10)
SET #MonthName='March' -- Here you need to pass month name
DECLARE #MonthNumber INT
SELECT #MonthNumber= CASE #MonthName
WHEN 'January' THEN 1
WHEN 'February' THEN 2
WHEN 'March' THEN 3
WHEN 'April' THEN 4
WHEN 'May' THEN 5
WHEN 'June' THEN 6
WHEN 'July' THEN 7
WHEN 'August' THEN 8
WHEN 'September' THEN 9
WHEN 'October' THEN 10
WHEN 'Nonvember' THEN 11
WHEN 'December' THEN 12
END
SELECT Id FROM MainTable
WHERE #MonthNumber BETWEEN DATEPART(MONTH,StartDate) AND DATEPART(MONTH,EndDate)
You need to pass MonthName query should work.
thanks
I have an issue retrieving the data that I would like. I have a Varchar column that consist of various information. I would like to extract the date from that column only. However, I have been unsuccessful. I used the following SQL(2008) to get the data below, But I can't seem to just get the date only without the time. Obviously, the date and time are in different position. Hope you can help.
SELECT substring(Data, 8, 17)
from mastInfo
9/25/2013 12:36:5
Jul 8 2013 11:40
9/25/2013 12:43:5
SELECT convert(date, Case When IsDate(substring(Data, 8, 17)) = 1
Then substring(Data, 8, 17)
Else NULL END)
from mastInfo
Since you are starting off with a string, it is possible that it does not represent a valid date. Using the IsDate function will return 1 when the string can be converted to a date. Basically, this code will convert to date those values that can be converted, and will return NULL for those values that cannot be converted to a valid date.
If you are using SQL Server 2012 or newer, then you can use Try_Convert().
Here's the SQL Fiddle.
Here's an example (from the above SQLFiddle):
Select Try_Convert(datetime, DateAsString) As DateAsDateTime
,DateAsString
From SomeTable
Here's the result:
DATEASDATETIME DATEASSTRING
September, 25 2013 12:36:05+0000 9/25/2013 12:36:5
September, 25 2013 12:43:05+0000 9/25/2013 12:43:5
July, 08 2013 11:40:00+0000 Jul 8 2013 11:40
if you want convert it to date time use :
SELECT CONVERT(Datetime, '2011-09-28 18:01:00', 120) -- to convert it to Datetime
if you want get time :
SELECT LTRIM(RIGHT(CONVERT(VARCHAR(20), '2011-09-28 18:01:00', 100), 7))
if you want date part :
SELECT CONVERT (DATE, GETDATE())
what version of sql server?
can you try this:
SELECT convert(date, substring(Data, 8, 17))
from mastInfo
First convert Varchar into DateTime and after that again convert it in varchar in desired date format like 101,102,103
Try this:
select convert(varchar(50),convert(datetime,'9/25/2013 12:43:5'),101)
In T-SQL what is the best way to convert a month name into a number?
E.g:
'January' -> 1
'February' -> 2
'March' -> 3
Etc.
Are there any built in functions that can do this?
How about this?
select DATEPART(MM,'january 01 2011') -- returns 1
select DATEPART(MM,'march 01 2011') -- returns 3
select DATEPART(MM,'august 01 2011') -- returns 8
How about this:
SELECT MONTH('March' + ' 1 2014')
Would return 3.
Its quit simple,
Take the first 3 digits of the month name and use this formula.
Select charindex('DEC','JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC')/4+1
SELECT DATEPART(MM,'january '+'01 1900')
SELECT MONTH('january ' + '01 1900')
SELECT month(dateadd(month,DATEDIFF(month,0,'january 01 2015'),0))
You can create a function and then refer to it in the select statement.
The function may look similar to this:
if OBJECT_ID('fn_month_name_to_number', 'IF') is not null
drop function fn_month_name_to_number
go
create function fn_month_name_to_number (#monthname varchar(25))
returns int as
begin
declare #monthno as int;
select #monthno =
case #monthname
when 'January' then 1
when 'February' then 2
when 'March' then 3
when 'April' then 4
when 'May' then 5
when 'June' then 6
when 'July' then 7
when 'August' then 8
when 'September' then 9
when 'October' then 10
when 'November' then 11
when 'December' then 12
end
return #monthno
end
Then you can query it.
select fn_month_name_to_number ('February') as month_no
This query will return 2 as month number.
You can pass values from a column as parameters to the function.
select fn_month_name_to_number (*columnname*) as month_no from *tablename*
Have a good day!
There is no built in function for this.
You could use a CASE statement:
CASE WHEN MonthName= 'January' THEN 1
WHEN MonthName = 'February' THEN 2
...
WHEN MonthName = 'December' TNEN 12
END AS MonthNumber
or create a lookup table to join against
CREATE TABLE Months (
MonthName VARCHAR(20),
MonthNumber INT
);
INSERT INTO Months
(MonthName, MonthNumber)
SELECT 'January', 1
UNION ALL
SELECT 'February', 2
UNION ALL
...
SELECT 'December', 12;
SELECT t.MonthName, m.MonthNumber
FROM YourTable t
INNER JOIN Months m
ON t.MonthName = m.MonthName;
I recently had a similar experience (sql server 2012). I did not have the luxury of controlling the input, I just had a requirement to report on it. Luckily the dates were entered with leading 3 character alpha month abbreviations, so this made it simple & quick:
TRY_CONVERT(DATETIME,REPLACE(obs.DateValueText,SUBSTRING(obs.DateValueText,1,3),CHARINDEX(SUBSTRING(obs.DateValueText,1,3),'...JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC')/4))
It worked for 12 hour:
Feb-14-2015 5:00:00 PM 2015-02-14 17:00:00.000
and 24 hour times:
Sep-27-2013 22:45 2013-09-27 22:45:00.000
(thanks ryanyuyu)
I think you may even have a separate table like a monthdetails (Monthno int, monthnames char(15)) and include values:
1 January
2 February
.... and so on, and then join this table with your existing table in the monthnames column
SELECT t1.*,t2.Monthno from table1
left outer join monthdetails t2
on t1.monthname=t2.monthnames
order by t2.Monthno
You can use below code
DECLARE #T TABLE ([Month] VARCHAR(20))
INSERT INTO #T
SELECT 'January'
UNION
SELECT 'February'
UNION
SELECT 'March'`
SELECT MONTH('01-' + [Month] + '-2010') As MonthNumeric,[Month] FROM #T
ORDER BY MonthNumeric
You can try sth like this, if you have month_name which is string datetype.After converting, you can feel free to order by Month.
For example, your table like this:
month
Dec
Jan
Feb
Nov
Mar
.
.
.
My syntax is:
Month(cast(month+'1 2016' as datetime))
You can do it this way, if you have the date (e.g. SubmittedDate)
DATENAME(MONTH,DATEADD(MONTH, MONTH(SubmittedDate) - 1, 0)) AS ColumnDisplayMonth
Or you can do it this way, if you have the month as an int
DATENAME(MONTH,DATEADD(MONTH, #monthInt - 1, 0)) AS ColumnDisplayMonth
I know this may be a bit too late but the most efficient way of doing this through a CTE as follows:
WITH Months AS
(
SELECT 1 x
UNION all
SELECT x + 1
FROM Months
WHERE x < 12
)
SELECT x AS MonthNumber, DateName( month , DateAdd( month , x , -1 )) AS MonthName FROM Months
try this
SELECT EXTRACT(MONTH FROM TO_DATE(month_added, 'Month')) AS month_number
select Convert(datetime, '01 ' + Replace('OCT-12', '-', ' '),6)