Extracting month number and converting it into month name in SQL Server - sql

I came across a SQL query:
select IssuedDate, Convert(char(4), IssuedDate, 0)
from TempTable
and this is its output:
IssuedDate Null
----------------------------------
1964-02-17 00:00:00.0000000 Feb
2018-08-28 00:00:00.0000000 Aug
2018-08-28 00:00:00.0000000 Aug
2018-08-28 00:00:00.0000000 Aug
Can anyone please let me know how the convert function is working and converting month number to month name?

This is using the default format for convert (the third argument is 0), which is "mon dd yyyy hh:miAM". That is, the first three characters in the formatted string are the month abbreviation.
The conversion is to a string with a length of four, it keeps only the first four characters. That would be the month abbreviation and the following character.
In my opinion, a more sensible approach would be:
left(datename(month, issueddate), 3)
This at least works for English, where the month abbreviations are the first the characters of the month name.

Related

Convert to datetime to specified format

I have been searching around for a while now, but I can't seem to find the answer to this small problem.
How to convert string 08-JUL-06 to datetime 08/07/1906? I've tried with code like the following:
select to_char(to_date('08-jul-06', 'dd-mon-rr'), 'dd/mm/yyyy') result from dual;
However, the result shows wrong: to be 08/07/2006? How do I solve the problem?
RR format is not suitable for this(*). How would Oracle know that you meant 1900s not 2000s? You know it because you know the context in which they occur. I suggest converting it to text and add 19 in front of the year yourself, like:
select to_date('19'||to_char(to_date('08-jul-06', 'dd-mon-yy'), 'yymmdd'),'yyyymmdd') result
from dual;
It is now a date, you can view it in the format you mentioned using to_char(...'dd-mon-yyyy'); or it might readily display like that if your Oracle installation date-format is that.
(*) If the specified two-digit year is 00 to 49, then
If the last two digits of the current year are 00 to 49, then the returned year has the same first two digits as the current year.
If the last two digits of the current year are 50 to 99, then the first 2 digits of the returned year are 1 greater than the first 2 digits of the current year.
If the specified two-digit year is 50 to 99, then
If the last two digits of the current year are 00 to 49, then the first 2 digits of the returned year are 1 less than the first 2 digits of the current year.
If the last two digits of the current year are 50 to 99, then the returned year has the same first two digits as the current year.
How to convert string 08-JUL-06 to datetime 08/07/1906?
You cannot, Oracle has two format models for handling two-digit years: YY and RR.
YY will assume the century is the current century.
RR will assume the century is:
The previous century if the specified year is 50-99 and the current year is 0-49
The current century if the specified year is 50-99 and the current year is 50-99
The current century if the specified year is 0-49 and the current year is 0-49
The next century if the specified year is 0-49 and the current year is 50-99
In none of these options will 06 assume that the full 4-digit year is 1906.
What you need to do is use a 4-digit year:
SELECT TO_CHAR(DATE '1906-07-08', 'dd/mm/yyyy') AS result FROM DUAL;
or, change your string to insert the century:
SELECT TO_CHAR(
TO_DATE(
SUBSTR(value, 1, 7) || '19' || SUBSTR(value, 8),
'DD-MON-YYYY',
'NLS_DATE_LANGUAGE=English'
),
'dd/mm/yyyy'
) AS result
FROM (SELECT '08-JUL-06' AS value FROM DUAL);
Which both output:
RESULT
08/07/1906
db<>fiddle here

How to convert "Wed Jan 26 2022" to date in sql?

I have varchar like this "Wed Jan 26 2022"
I need to convert this to date in sql. How can i do this
for Sql Server:
convert(date, substring('Wed Jan 26 2022',5,11),9)
we ignore the Day name (superfluous), and convert the rest using format 9 indicating Mon dd yyyy format.
SQL*plus server (Here's my code) -
If I am right, you want such type of string which is an invalid one to convert that into a valid one so that you can store valid data into the database. then this code you can use->
SELECT TO_DATE('WED JAN 26 2022','DY MON DD YYYY')FROM DUAL;
(Explanation)->
Code will convert invalid date datatype to a valid date data type which is used in Oracle(SQL).
DY = Abbreviated Week Day
DD = Month day indicator
MON = Abbreviated month
YYYY = Four-digit year indicator

HOW TO FETCH DATA BETWEEN 2 DATES IN ORACLE SQL DEVELOPER

I'm new to oracle sql . I want to fetch data between 2 dates .
Date is in this format in db : 13-DEC-10
This is the query I have written but its giving me error . How to proceed next
select sum(TOTAL_AMOUNT) from table a
where trn_date between
TO_DATE(01-APR-17, 'DD-MON-YYYY') AND TO_DATE(31-MAR-17, 'DD-MON-YYYY') ;
A date does not have a format - it is stored internally to the database as 7-bytes (representing year, month, day, hour, minute and second) and it is not until whatever user interface you are using (i.e. SQL/Plus, SQL Developer, Java, etc) tries to display it to you, the user, and converts it into something you would find meaningful (usually a string) that the date has a format.
To fix your query you just need to surround the date string in single quotes and to use YY to match the 2-digit year format (otherwise Oracle will assume that 17 in the format YYYY is the year 0017 and the century will not be as you expect):
select sum(TOTAL_AMOUNT)
from table a
where trn_date between TO_DATE('01-APR-17', 'DD-MON-YY')
AND TO_DATE('31-MAR-17', 'DD-MON-YY');
However, you can also use date literals (and skip having to match the date format model):
select sum(TOTAL_AMOUNT)
from table a
where trn_date between DATE '2017-04-01'
AND DATE '2017-05-31';
Alternatively you may use the year format of RR format against centurial problems, Don't forget to keep quotes for date values, and you may prefer calling sql with bind variables :
select sum(TOTAL_AMOUNT)
from table a
where trn_date between
TO_DATE('&date_1', 'DD-MON-RR') AND TO_DATE('&date_2', 'DD-MON-RR') ; -- where date_1 is 31-MAR-17 and date_2 is 01-APR-17, in your case.
What I mentioned by centurial problems :
The RR Datetime Format Element
The RR datetime format element is similar to the YY datetime format
element, but it provides additional flexibility for storing date
values in other centuries. The RR datetime format element lets you
store 20th century dates in the 21st century by specifying only the
last two digits of the year.
If you use the TO_DATE function with the YY datetime format element,
then the year returned always has the same first 2 digits as the
current year. If you use the RR datetime format element instead, then
the century of the return value varies according to the specified
two-digit year and the last two digits of the current year.
That is:
If the specified two-digit year is 00 to 49, then
If the last two digits of the current year are 00 to 49, then the
returned year has the same first two digits as the current year.
If the last two digits of the current year are 50 to 99, then the
first 2 digits of the returned year are 1 greater than the first 2
digits of the current year.
If the specified two-digit year is 50 to 99, then
If the last two digits of the current year are 00 to 49, then the
first 2 digits of the returned year are 1 less than the first 2 digits
of the current year.
If the last two digits of the current year are 50 to 99, then the
returned year has the same first two digits as the current year.

how to get the exact year from the given date in oracle if it has a minimal format to base from?

how to get the exact "year" from oracle data if the given data is in this format?
02-FEB-84
I want to get the year, but when I do something like this
case
when dob is not null then to_date(dob,'YYYY')
when dob is null then '""'
end
as yearofbirth
I am getting the value of
2084
when I was expecting
1984
how to solve this?, because my query is not smart enough to determine if the year is from the 19th century or 20th century
Assuming DOB is varchar2() having date in format DD-MON-YY,
You might be looking for
TO_CHAR(TO_DATE(DOB,'DD-MON-RR'),'YYYY')
Conversion using YY format! Current century is 20** so, 84 -> 2084
SQL> SELECT TO_CHAR(TO_DATE('02-FEB-84','DD-MON-YY'),'YYYY') FROM DUAL;
TO_C
----
2084
Conversion using RR format! Current century is 20** and year is < 2050 so, 84 -> 1984
SQL> SELECT TO_CHAR(TO_DATE('02-FEB-84','DD-MON-RR'),'YYYY') FROM DUAL;
TO_C
----
1984
One more condition to your case statement should do it.
case
when to_date(dob) > sysdate then to_date(dob,'YYYY') - 100
when dob is not null then to_date(dob,'YYYY')
when dob is null then '""'
end
as yearofbirth
It's tricky, for example:
TO_DATE('16/06/66','DD/MM/RRRR')
16/06/1966
TO_DATE('16/06/16','DD/MM/RRRR')
16/06/2016
TO_DATE('16/06/16','DD/MM/RRRR')
16/06/1916
For the RRRR mask a value between 0-49 will return a 20xx year. A value between 50-99 will return a 19xx year.
You just hit the Y2K bug. You need to use the 'RR' format to get the proper YEAR result in 2 digits.
If you have used 'RR' format than it understands it as 1984 and if you have use 'YY' format it understands as 2084.
In general A value between 0-49 will return a 20xx year.
A value between 50-99 will return a 19xx year.
select to_date('84','RR') from dual
Always, remember, an year must be YYYY(4 digits) and not YY. The world has already spent too much time fixing the Y2K bug.
You can read more about 'RR' format here http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#SQLRF00215
Update : You need to use to_char if you want to display the year using 'RR' format.
Select to_char(dob,'RR') from table
I assume your dob column is DATE data type. A date must always be DATE data type and NOT string. Else, you need to first convert the literal into date and use to_char over it with 'RR' format.
TO_CHAR(YOUR_TABLE_DATA_COLUMN,'YYYY')

Need to identify number that is higher than a given date

I have a date column in a table. The date column is in varchar. I want to identify a particular date range from that date column. My query is like this:
SELECT *
FROM [003 AccptReg].[dbo].[SysData1]
WHERE [RegDate_Sys] > '18 jul 2013'
But the result is not giving accurate result, i.e. it gives dates which are prior of 18 jul 2013.
Is there any thing wrong I am doing?
For date column, you should compare as DATE
select * from [003 AccptReg].[dbo].[SysData1]
where CAST([RegDate_Sys] AS DATE) > CAST('18 jul 2013' AS DATE)
The problem is that you have the date as a varchar, and doesn't convert it to a date when you are doing the comparison. The database doesn't know that you see the data as dates, and will simply compare them as strings, so for example '2 jan 1736' will be larger than '18 jul 2013' because 2 comes after 1.
The best would be if you could store the data as datetime values (or date), then you don't need to do the conversion when you compare the values, which would give better performance.
If that's not possible, do the conversion in the query:
select * from [003 AccptReg].[dbo].[SysData1]
where convert(datetime, [RegDate_Sys], 106) > '18 jul 2013'
Depending on the settings on the server, you might also need to convert '18 jul 2013' in the same way for the database to understand it correctly as a date.
Convert the date to datetime format and then compare:
select * from [003 AccptReg].[dbo].[SysData1]
where convert(datetime,[RegDate_Sys]) >convert(datetime,'18 jul 2013')