Oracle SQL: Transpose Columns to Rows After Using Extract - sql

I have a table with column DATE. Date is 'dd/mm/yyyy' and I want only days. So I try with extract and return what I need, but I what using transpose for column to row.
The select statement is:
select EXTRACT (DAY FROM "DATE") DAY
from people;
Is this thing possible?
Thank you!

If you have a string, then just use the leftmost two characters:
select substr("DATE", 1, 2) as day
That said, you should not be storing dates as strings. It is wrong, wrong, wrong. You cannot use the built-in date/time functions. You cannot use inequality comparisons either. Fix your data model.

The date format doesn't matter. It is linked to your NLS local settings and this is how you see this.
To have it generic and extract DAY from the date do this:
select to_char(sysdate, 'DD') from dual;
Would return 07 since it's September 7th 2020.

Related

How to extract month number from date in Oracle

I have ID_BB_SECURITY column where the date value is stored in this column for example '20190801'.
I want to get month number from this field for example for August date i want to get 8.
I tried below query but it throws an error 'literal does not match':
select to_number(to_date(ID_BB_SECURITY),'mm') from BT_EXPORT
I am not sure if i have to ignore null values so as to avoid the error
If the value is a number or string then you can convert it to a date with an appropriate mask - which is what you are missing, and what is causing the error you are getting (as it's using your session's NLS_DATE_FORMAT setting, which apparently does not match the format of the data; but which you should not rely on anyway, as #MTO said in comments):
to_date(ID_BB_SECURITY, 'YYYYMMDD')
and then extract the month number from that:
select extract(month from to_date(ID_BB_SECURITY, 'YYYYMMDD')) from BT_EXPORT
Or you could just use a substring:
select to_number(substr(ID_BB_SECURITY, 5, 2)) from BT_EXPORT;
Those assume a fixed consistent format, which is always a risky assumption when using the wrong data type. Ans if it's a number they are doing an implicit conversion from number to string, which you could turn into an explicit conversion for greater clarity.
If it's already a date - as it should be, of course - then you don't need the conversion:
select extract(month from ID_BB_SECURITY) from BT_EXPORT
If you have a number, you can use arithmetic to extract the month:
select mod(floor(20190801 / 100), 100)
from dual;
You could try converting the number date to a string, and then extracting the 5th and 6th characters:
SELECT
SUBSTR(TO_CHAR(ID_BB_SECURITY), 5, 2) AS mm
FROM BT_EXPORT;
But, it would be much better for you to use a proper date column. Then, you could use a less draconian method such as:
SELECT
TO_CHAR(ID_BB_SECURITY, 'mm') AS mm -- assuming date
FROM BT_EXPORT;
select to_number(to_char(to_date('20190801', 'yyyymmdd'), 'mm')) from dual
Try this one
select extract(month from to_date(ID_BB_SECURITY, 'YYYYMMDD')) from BT_EXPORT
This one convert number to date then extract month.
also
select extract(month from to_date('20190801', 'yyyymmdd')) from dual
Your date column has the value stored in the following format "yyyymmdd" where
yyyy is the year
mm the month
dd the day
So in order to return the number value of the month (mm) we can do as follows:
1: first transform the value from a number to a date using
to_date(20190801,'yyyymmdd')
2: get month using to_date operator
to_char( to_date(20190801,'yyyymmdd'), 'mm')

How to compare 2 converted dates in sql

I'm trying to exclude results in my query that start in the same month between two columns. For example, I need to exclude benefits1 that start in the same month as benefits2. Format for benefit1_start_date and benefit2_start_date is: YYYYMMDD.
This is what I have so far:
where (benefit1_start_date = (to_char(sysdate, 'YYYYMM') || '0122')) <>
(benefit2_start_date = (to_char(sysdate, 'YYYYMM') || '0122'));
If anyone could put me in the right direction, I'd greatly appreciate it!
Convert your numeric dates to text, and then compare the year and month substrings:
WHERE
SUBSTR(TO_CHAR(benefits1_start_date), 1, 6) <> SUBSTR(TO_CHAR(benefits2_start_date), 1, 6)
Note that storing your dates as numbers like this is atypical, and you might want to consider storing them as dates. If you don't have a day component, you could just use the first as a placeholder.
As I understand it, you want to eliminate records where your 2 columns benefits1_start_date and benefits2_start_date are in the same month, and both have a format of YYYYMMDD.
Are they stored as strings? If so, all you need to do is compare the first 6 characters (if you need to consider yr + month), or just the 5+6th characters if you want to check just the month without the year.
Year + Month:
SUBSTR(benefits1_start_date,1,6) <> SUBSTR(benefits2_start_date,1,6)
Just month:
SUBSTR(benefits1_start_date,5,2) <> SUBSTR(benefits2_start_date,5,2)
If they're not stored as strings but as dates, then you can TRUNC the date to month and compare (for yr + month), or convert the date to MM string via to_char and compare if you just want to check the month.
Hope this helps.
I suggest you to use BETWEEN clause. Converting LEFT side operand to string by function and then making comparison can have severe performance impacts.
if you convert indexed table.dateColumn to string by to_char(table.dateColumn), oracle cannot use defined index on column anymore.
Your desired query:
where to_char(benefit1_start_date, 'YYYYMM') != to_char(benefit2_start_date, 'YYYYMM')
but
select * from table1
where months_between(benefit1_start_date, benefit2_start_date) not between -1 and 1
would be what you are looking for. (no performance impact)

Format date where the position of the parts is variable

We have a file that needs to be imported that has dates in it. The dates are in a format that I have not seen before and the day part can vary in length (but not the month or year seemingly) and position based on wether the number is double digit or not, i.e.
Dates:
13082014 is 13th February 2014
9092013 is 9th September 2013
The current script tries to substring the parts out, but fails on the second one as there is not enough data. I could write an if or case to check the length, but is there a SQL format that can be used to reliably import this data?
To clarify this is MSSQL and the date format is ddmmyyyy or dmmyyyy
One of the simple way is using STUFF.
example:
select STUFF(STUFF('13082014 ',3,0,'/'),6,0,'/');
//result: 13/08/2014
Good luck.
LPAD a zero when it is missing so to always get an eight character date string. Here is an example with Oracle, other DBMS may have other string and date functions to achieve the same.
select to_date(datestring, 'ddmmyyyy')
from
(
select lpad('13082014', 8, '0') as datestring from dual
union all
select lpad('9092013', 8, '0') as datestring from dual
);
Result:
13.08.2014
09.09.2013
you can convert the dates to a relevant date format then import data(based on the dateformat change the logic).
something like this :
select Convert(varchar(10),CONVERT(date,YourDateColumn,106),103)

Filtering by date

I have a Date type column where are values in this format
1.1.2012 10:10:11
I need to create a filter which would filter these values by day, month and year.
I've tried
where like '% 1.1.2012 %'
but this seems to not working.
Oracle not store your date field formatted, but you can format the output with to_char function. For example:
select to_char(date_field,'dd/mm/yyyy hh24:mi:ss')
If you query a date without formatting, the output format will depend on the tool that you are using and your NLS_DATE parameter too.
To filter dates in Oracle you can use the to_date function, that receives an string and parse to date with some specific format. You can see all options of to_date here
Options to filter your date field:
where date_field between to_date('1.1.2012 00:00','d.m.yyyy hh24:mi') and to_date('1.1.2012 23:59','d.m.yyyy hh24:mi')
-- you possibly will lost some performance with this second one
where trunc(date_field) = to_date('1.1.2012','d.m.yyyy')
In MSSQL, you can use date-functions, that are easy to handle. One way would be like this:
where Year (date) = 2012
and Month(date) = 1
and Day (date) = 1
But there are other solutions. Take a look at the following page for mor information:
http://msdn.microsoft.com/en-us/library/ms186724.aspx
I worked recently with string-representations of datetime-values. I recommend not do it and to work always with the dates, because of compatibility, speaking of the MSSQL-Server.
If you use string-representations of datetime-values you need to be very careful with formats on different language-settings than the one on your own server.
Strings can be interpreted different on other servers (ISO-format vs us-format).
One possibility would be to do something like this:
WHERE date_and_time >=to_date( '01.01.2012','dd.mm.yyyy') and date_and_time <= to_date('01.01.2012','dd.mm.yyyy');
date_and_time is the name of your Date column.
edit: This is for Oracle

SQL query to convert Date to another format

Thanks for your help. I am not able to make out the type/format of the "Value" in a Date column.I guess its in Julian Date format.
The Column is paid_month and the values are below.
200901
200902
So,please help in writing SQL query to convert the above values(Mostly in Julian Format) in the Date Column to normal date (MM/DD/YYYY) .
Thanks
Rohit
Hi,
I am sorry for missing in giving the whole information.
1)Its a Oracle Database.
2)The column given is Paid_Month with values 200901,200902
3)I am also confused that the above value gives month & year.Day isnt given if my guess is right.
4)If its not in Julian format ,then also please help me the SQL to get at least mm/yyyy
I am using a Oracle DB and running the query
THANKS i GOT THE ANSWER.
**Now,i have to do the reverse meaning converting a date 01/09/2010 to a String which has 6 digits.
Pls help with syntax-
select to_char(01/01/2010,**
It looks like YYYYMM - depending on your database variant, try STR_TO_DATE(paid_month, 'YYYYMM'), then format that.
Note: MM/DD/YYYY is not "normal" format - only Americans use it. The rest of the world uses DD/MM/YYYY
For MySQL check
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date-format
Example:
SELECT DATE_FORMAT(NOW(), '%d/%m/%Y')
For MySQL, you would use the STR_TO_DATE function, see http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_str-to-date
SELECT STR_TO_DATE(paid_month,'%Y%m');
Sounds like the column contains some normal dates and some YYYYMM dates. If the goal is to update the entire column, you can attempt to isolate the YYYYMM dates and update only those. Something like:
UPDATE YourTable
SET paid_month = DATE_FORMAT(STR_TO_DATE(paid_month, '%Y%m'), '%m/%d/%Y')
WHERE LENGTH(paid_month) = 6
SELECT (paid_month % 100) + "/01/" + (paid_month/100) AS paid_day
FROM tbl;
I'm not sure about how oracle concatenates strings. Often, you see || in SQL:
SELECT foo || bar FROM ...
or functions:
SELECT cat (foo, bar) FROM ...