Sql Change Time in Query - sql

I currently have the following Problem, working on an Oracle Database:
I have 2 columns of an appointment I want to read: date_from and date_to. They have both DateTime as the datatype.
I need to adjust the time of the value though (and only the time, the date should stay the same).
date_from for example contains 10.10.2017 14:21:00 as a value,
but should be changed to the "start of the day" --> 10.10.2017 00:00:00
date_to for example contains 11.10.2017 11:47:00 as a value,
but should be changed to the "end of the day" --> 10.10.2017 23:59:59
Is this somehow possible to manipulate it this way? I can not do an Update or permanent change to the data. This Format is only needed for a Gantt Diagramm, I dont have an other way to change it.
Thank you in Advance!

Yes, you can achieve that with Oracle's TO_DATE and TO_CHAR functions. It will only depend if you need the result as a DATE or as a VARCHAR. The syntax would look like this for VARCHAR output:
TO_CHAR(date_from, 'DD.MM.YY') || ' 00:00:00'
TO_CHAR(date_to, 'DD.MM.YY') || ' 23:59:59'
If you need the DATE value from this, just add the TO_DATE funtion around it:
TO_DATE((TO_CHAR(date_from, 'DD.MM.YY') || ' 00:00:00'), 'DD.MM.YY HH24:MI:SS')
TO_DATE((TO_CHAR(date_to, 'DD.MM.YY') || ' 23:59:59'), 'DD.MM.YY HH24:MI:SS')
I did not test it, but it's pretty much it.
Does this helps?
Cheers
Nikao

If you need to show the result, try this:
select to_char(date_from, 'DD.MM.YYYY') ||' 00:00:00' as date_from,
to_char(date_to, 'DD.MM.YYYY') ||' 23:59:59' as date_to
from table_name
But you may need to compare intervals. In this case, you could discarts the time using trunc function:
select *
from table_dates t,
other_table o
where trunc(o.some_date) between trunc(t.date_from) and trunc(t.date_to)
UPD: First, I did an implicit conversion of dates to string using TRUNC. But it can lead to inexpected result. Instead, explicitly use TO_CHAR with the format model you are expecting for your output and you do not need to use TRUNC. (Thank you #MT0 )

So you want to return the start and end of the day?
select trunc(start_date) as day_start, -- Strips off the time part of the date
trunc(end_date) + 1 - (1/86400) as day_end -- As above, but we add 1 day and minus 1 second
from My_Table
Also, Oracle has date formats of Date and Timestamp, no datetime

this might be some help to you:
SELECT to_char(current_timestamp,'yyyy-mm-dd hh:mm:ss') FROM dual;
SELECt trunc(current_timestamp)||' 23:59:59' FROM dual;

Related

Filtering a dataset by date and time Oracle SQL through Power BI

I'm having trouble with filtering a date and time for anything two hours before and sooner. I tried this:
SELECT *
FROM
table
where
date >= sysdate - 1
AND
TO_DATE( Time, 'HH24:MI:SS' ) >= TO_DATE( sysdate, 'HH24:MI:SS' ) - 2
But I'm getting an inconsistent type error which is what I thought I was handling with the TO_DATE() function but I guess not.
sysdate is already a date (and time), so TO_DATE( sysdate, 'HH24:MI:SS' ) doesn't make any sense.
You didn't provide your data types for your date and time columns in table, so I'm going to assume they're both varchar2(10) with formats MM/DD/YYYY and HH24:MI:SS respectively.
I'm also going to go ahead and change your example table and column names, since they're invalid names to use in a real query.
-- example data
with my_table as (select '06/13/2019' as date_column, '09:40:34' as time_column from dual)
-- your query
SELECT *
FROM
my_table
where
to_date(date_column || ' ' || time_column, 'MM/DD/YYYY HH24:MI:SS') >= sysdate - 2/24
What I'm doing here is to combine your date and time strings into one date-time string, then converting it to an Oracle date type (actually date+time). Then we compare it to sysdate - 2/24, which says to take the current time and subtract 2/24ths of a day, which is 2 hours.
For this example, you might need to change the example data date_column and time_column values to something from the past 2 hours, depending on when you run this and what time zone you're in.

Oracle, finding data between two different dates

I have a table name as business_details and column name business_date whose data type is varchar2.
Now i have to find out the data between two different dates and date format like : 12-JUN-18 21:15:13
Means, 12 Jun, 2018.
Kindly help me to write a query which can fetch the data between these two dates :12-JUN-18 21:15:13 and 25-JUN-18 18:15:32
I assume that in table business_details you have an column date or something like that.
Than use something like this:
select business_date from business_details
where date between TO_DATE ('12-JUN-18 21:15:13','dd-MM-yy hh:mi:ss')
AND TO_DATE ('25-JUN-18 18:15:32','dd-MM-yy hh:mi:ss');
Assuming your business_date is actually a string in the format you've shown (and it isn't really a date your client is just showing in that format), you need to convert that to a date type, as well as converting the string literals.
select *
from business_details
where to_date(business_date, 'DD-MON-RR HH24:MI:SS')
between to_date('12-JUN-18 21:15:13', 'DD-MON-RR HH24:MI:SS')
and to_date('25-JUN-18 18:15:32', 'DD-MON-RR HH24:MI:SS');
The format model you tried to use in a comment did this:
to_date('12-JUN-18 21:15:13', 'DD-MM-YYYY HH24:MI:SS')
is using MM rather than MON, which works anyway by default - although using month numbers is safer anyway as they aren't dependent on your session language. But more importantly it uses YYYY. If you pass a 2-digit value like 18 and try to convert with YYYY you get the wrong year:
select to_date('12-JUN-18 21:15:13', 'DD-MON-YYYY HH24:MI:SS') form dual;
TO_DATE('12-JUN-182
-------------------
0018-06-12 21:15:13
In your version your business_date was being converted implicitly so would use NLS settings, which are presumably using RR already. But that means you were comparing a date in 2018 with a range in 0018, which is why nothing matched.
You could also use timestamp literals for the fixed values (unless those strings are actually being passed in from somewhere else):
select *
from business_details
where to_date(business_date, 'DD-MON-RR HH24:MI:SS')
between cast(timestamp '2018-06-12 21:15:13' as date)
and cast(timestamp '2018-06-25 18:15:32' as date);

SQL time and date formatting against dual table

I am trying to only display the date and time of a table in a certain format. This format is DD-MON-YYYY and the time HH24:MI:SS. I don't understand how to make both formats work together. I can get them to function separately.
select to_char(sysdate, 'DD-MON-YYYY', systimestamp,'HH24:MI:SS') from dual;
My error is 'too many arguments'. I want to understand why it isn't working.
From the documentation TO_CHAR takes three arguments when using dates
a date or date time
a format model
optional NLS parameter for the localization
You can concatenate the two results together with this.
select to_char(sysdate, 'DD-MON-YYYY')||' '|| TO_CHAR(systimestamp,'HH24:MI:SS') from dual;
But why would when you do it one call
SELECT TO_CHAR(systimestamp,'DD-MON-YYYY HH24:MI:SS') from dual;
NB SQL is not case sensitive in regards to keywords. Upper or lower case both work.
Try:
select to_char(sysdate, 'DD-MON-YYYY HH24:MI:SS') from dual;

Getting rid of the time in a date

SELECT close_date, close_UIN, count(*) as Amount_Closed_per_employee
FROM t_return_master
where status = 'C' AND TO_DATE (close_date ,'DD-MON-YY') BETWEEN TO_DATE
('~Date From~', 'DD/MM/YYYY') AND TO_DATE('~Date To~','DD/MM/YYYY')
group by close_date, close_UIN
order by close_UIN
I have the code you see above, at the moment it displays the hours, minutes and seconds when it displays the close date, however as I am grouping by close date, I need this to go so it group by date only. Anyone any ideas how I can do this?
You can use TRUNC() on the date (in the SELECT and GROUP BY clauses) which, with just the default argument, sets the hours/minutes/seconds/milliseconds to zero.
SELECT TRUNC( close_date ) AS close_date_day,
close_UIN,
count(*) as Amount_Closed_per_employee
FROM t_return_master
where status = 'C'
AND TO_DATE (close_date ,'DD-MON-YY')
BETWEEN TO_DATE('~Date From~', 'DD/MM/YYYY')
AND TO_DATE('~Date To~','DD/MM/YYYY')
group by TRUNC( close_date ), close_UIN
order by close_UIN
The simplest way is to use the trunc() function, which by default sets the time portion of the date value to midnight:
SELECT trunc(close_date), close_UIN, ...
...
group by trunc(close_date), close_UIN
order by close_UIN
Note that you need to truncate the value in the select list and the group-by clause. The function can optionally truncate to a different precision too, like removing seconds, or going to the first day of the month, etc.:
select sysdate, trunc(sysdate), trunc(sysdate, 'SS') from dual;
SYSDATE TRUNC(SYSDATE) TRUNC(SYSDATE,'MI')
------------------- ------------------- -------------------
2015-05-01 09:37:48 2015-05-01 00:00:00 2015-05-01 09:37:00
See the docs for more info.
This is not correct:
AND TO_DATE (close_date ,'DD-MON-YY') BETWEEN TO_DATE
('~Date From~', 'DD/MM/YYYY') AND TO_DATE('~Date To~','DD/MM/YYYY')
Since close_date is already a date column you're doing an implicit conversion to a string using your NLS_DATE_FORMAT, and then an explicit conversion back to a date using 'DD-MON-YY' - which is using a two-digit year and will cause its own problems. The behaviour may vary for other users with different settings.
It looks like you're trying to do the equivalent of a trunc() to make the between cover the whole of the final day, but you won't get the year (century) you expect. And calling any function on the column will prevent any index on it being used, unless you have a matching function-based index (but using trunc() only in the select list and group by is OK).
If you want all records from the start of 'date from' to the end of 'date to' you can specify that with a range instead of 'between' - which is inclusive but might not get the result you expect depending on your NLS settings, again. Something like:
AND close_date >= TO_DATE('~Date From~', 'DD/MM/YYYY')
AND close_date < TO_DATE('~Date To~','DD/MM/YYYY') + 1
Less than midnight on the day after 'date to' is equivalent to saying up to 23:59:59 on 'date to', i.e. covering that entire day.

How to change the date format from MM/DD/YYYY to YYYY-MM-DD in PL/SQL?

I have a date column in a table stored as MM/DD/YYYY format. I have to select and store the same date in another table in YYYY-MM-DD format i.e. XSD Date Format. But I am not able to do it. I am using this query:
select to_date(date_column,'YYYY-MM-DD') from table;
But still I am not able to do it. Giving me error
ORA-01843 : not a valid month
use
select to_char(date_column,'YYYY-MM-DD') from table;
It sounds like you've got it the wrong way round. If your existing data is in MM/DD/YYYY format, then you want:
select to_date(date_column,'MM/DD/YYYY') from table;
to convert the existing data to DATE values. (I do wonder why they're not stored as dates, to be honest...)
If you want to perform the conversion in one step, you might want:
select to_char(to_date(date_column,'MM/DD/YYYY'), 'YYYY-MM-DD') from table;
In other words, for each row, parse it in MM/DD/YYYY format, then reformat it to YYYY-MM-DD format.
(I'd still suggest trying to keep data in its "natural" type though, rather than storing it as text in the first place.)
I assume that you can use the Oracle SQL Developer, which you can download from here.
You can define the date format which you want to work with:
ALTER SESSION SET nls_date_format='yyyy-mm-dd';
With this, now you can perform a query like this:
SELECT * FROM emp_company WHERE JDate = '2014-02-25'
If you want to be more specific you can define the date format like this:
ALTER SESSION SET nls_date_format='yyyy-mm-dd hh24:mi:ss';
To convert a DATE column to another format, just use TO_CHAR() with the desired format, then convert it back to a DATE type:
SELECT TO_DATE(TO_CHAR(date_column, 'DD-MM-YYYY'), 'DD-MM-YYYY') from my_table
select to_date(to_char(ORDER_DATE,'YYYY/MM/DD'))
from ORDERS;
This might help but, at the end you will get a string not the date. Apparently,
your format problem will get solved for sure .
For military time formatting,
select TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mm:ss') from DUAL
--2018-07-10 15:07:15
If you want your date to round DOWN to Month, Day, Hour, Minute, you can try
SELECT TO_CHAR( SYSDATE, 'yyyy-mm-dd hh24:mi:ss') "full-date" --2018-07-11 10:40:26
, TO_CHAR( TRUNC(SYSDATE, 'year'), 'yyyy-mm-dd hh24:mi:ss') "trunc-to-year"-- 2018-01-01 00:00:00
, TO_CHAR( TRUNC(SYSDATE, 'month'), 'yyyy-mm-dd hh24:mi:ss') "trunc-to-month" -- 2018-07-01 00:00:00
, TO_CHAR( TRUNC(SYSDATE, 'day'), 'yyyy-mm-dd hh24:mi:ss') "trunc-to-Sunday" -- 2018-07-08 00:00:00
, TO_CHAR( TRUNC(SYSDATE, 'dd'), 'yyyy-mm-dd hh24:mi:ss') "trunc-to-day" -- 2018-07-11 00:00:00
, TO_CHAR( TRUNC(SYSDATE, 'hh'), 'yyyy-mm-dd hh24:mi:ss') "trunc-to-hour" -- 2018-07-11 10:00:00
, TO_CHAR( TRUNC(SYSDATE, 'mi'), 'yyyy-mm-dd hh24:mi:ss') "trunc-to-minute" -- 2018-07-11 10:40:00
from DUAL
For formats literals, you can find help in
https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions242.htm#SQLRF52037
You can do this simply by :
select to_char(to_date(date_column, 'MM/DD/YYYY'), 'YYYY-MM-DD') from table
According to the comments, the data-type in the datatable is DATE.
So you should simply use:
"select date_column from table;"
Now if you execute the select you will get back a date data-type, which should be what you need for the .xsd.
Culture-dependent formating of the date should be done in the GUI (most languages have convenient ways to do so), not in the select-statement.
Basically , Data in a Date column in Oracle can be stored in any user defined format or kept as default.
It all depends on NLS parameter.
Current format can be seen by : SELECT SYSDATE FROM DUAL;
If you try to insert a record and insert statement is NOT in THIS format then it will give :
ORA-01843 : not a valid month error.
So first change the database date format before insert statements ( I am assuming you have bulk load of insert statements) and then execute insert script.
Format can be changed by :
ALTER SESSION SET nls_date_format = 'mm/dd/yyyy hh24:mi:ss';
Also You can Change NLS settings from SQL Developer GUI , (Tools > preference> database > NLS)
Ref: http://oracle.ittoolbox.com/groups/technical-functional/oracle-sql-l/how-to-view-current-date-format-1992815
This worked for me! You can convert to datatype you want be it a date or string
to_char(TO_DATE(TO_CHAR(end_date),'MM-DD-YYYY'),'YYYY-MM-DD') AS end_date
Late reply but for.databse-date-type the following line works.
SELECT to_date(t.given_date,'DD/MM/RRRR') response_date FROM Table T
given_date's column type is Date
Just to piggy back off of Yahia, if you have a timestamp you can use this function to cast exclusively as date, removing the timestamps.
TO_CHAR(CAST(DateTimeField AS DATE), 'YYYY-MM-DD') AS TrackerKey__C
Or in my case I need the below format
TO_CHAR(CAST(DateTimeField AS DATE), 'YYYYMMDD') AS TrackerKey__C
SELECT TO_DATE(TO_CHAR(date_column,'MM/DD/YYYY'), 'YYYY-MM-DD')
FROM table;
if you need to change your column output date format just use to_char this well get you a string, not a date.
use
SELECT STR_TO_DATE(date_column,'%Y-%m-%d') from table;
also gothrough
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html