How Should I Represent Time of Day in an Oracle database? - oracle

I would like to store time of day - e.g. 18:00 in an Oracle database, and would like to do comparison queries with it.
What is the recommended way to represent a time of day column?

You can use a column with datetime typoe and so yo can perform comparisio on datetime column and show th time with to_char(datetime)
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions180.htm
eg :
SELECT TO_CHAR(your_col, 'HH24:MI')
FROM your_table;
for format models see http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm

Related

Oracle select date without time and keep date as data type

I have a column name 'Cos_Date' with value like 14APR2017:00:00:00.
However, for a new column name 'Arrival_Date', I would like to keep the date information but omit time, and keep the data type as Date but not Character. Ex, 14APR2017.
I have tried:
select TO_CHAR(Cos_Date, 'DD-MON-YYYY') ARRIVAL_DATE
But it will delete time information, but data type turns to Character.
I search on this site, and tried both:
select TO_DATE(TO_CHAR(Cos_Date, 'DD-MON-YYYY'), 'DD-MON-YYYY') ARRIVAL_DATE
and:
select TRUNC(Cos_Date) ARRIVAL_DATE
But it will not omit time information.
Can I try something else?
Thank you!
You can't "omit" the time portion of a DATE column in Oracle. The DATE data type always contains a time component. If you don't want to see the time, don't display it, e.g.,
SELECT TO_CHAR(TRUNC(Cos_Date),'DD-MON-YYYY') FROM dual;
In Oracle there is no date data type that has only a year-month-day component.
The DATE data type is stored internally as 7- or 8-bytes which always has year (2-bytes), month (1-byte), day (1-byte), hour (1-byte), minute (1-byte) and second (1-byte).
The TIMESTAMP data type also has fractional seconds (and can also have a time zone).
Can I try something else?
No, you either use a VARCHAR2 string or use a DATE or TIMESTAMP and accept that it has a time component.
Selecting date values without time:
SELECT date_col
FROM table
WHERE TO_CHAR (date_col, 'HH24:MI:SS') = '00:00:00';

Unixtimestamp time difference in SQL Query

I want to get time difference with UNIXTIMESTAMPin SQL. I want to retrieve data from database that queries inserted reports like week, month. I am inserting with UNIXTIMESTAMP. So I want to get the difference between CURRENT_TIMESTAMP and query inserted date.
you would need to convert the UNIXTIMESTAMP to date time format before you can find the difference. here is a post from oracle community to convert UNIXTIMESTAMP to date time value
https://community.oracle.com/thread/302756?start=0&tstart=0

Oracle Is there a way to update date and not month, year

Is there a way to update the date part of a column of type Date. For example, a row in the DB has value 2013-11-22 [stored in YYYY-MM-DD format]. And I want to update it to 2013-11-01.
If it had been one or few rows I could have done a simple update. But the real problem is that there are about hundred thousand rows with different date values. And I want to update all the dates to the 1st of each month. For example
Actual What I would like it to be
2013-01-22 2013-01-01
1989-10-03 1989-10-01
2004-07-01 2004-07-01
2005-12-31 2005-12-01
Would appreciate any help, how can i get this done through SQL. Thanks in Advance.
Assuming that the data type is a date, use trunc
TRUNC(date_column, 'mm')
Here is a sqlfiddle demo
Yes, you can use the trunc() function.
For example:
UPDATE thetable set datevalue = trunc(datevalue, 'MM');

Querying a data warehouse data involving time dimension

I have two tables for time dimension
date (unique row for each day)
time of the day (unique row for each minute in a day)
Given this schema what would a query look like if one wants to retrieve facts for last X hours where X can be any number greater than 0.
Things start to be become tricky when the start time and end time happen to be in two different days of the year.
EDIT: My Fact table does not have a time stamp column
Fact tables do have (and should have) original timestamp in order to avoid weird by-time queries which happen over the boundary of a day. Weird means having some type of complicated date-time function in the WHERE clause.
In most DWs these type of queries are very rare, but you seem to be streaming data into your DW and using it for reporting at the same time.
So I would suggest:
Introduce the full timestamp in the fact table.
For the old records, re-create the timestamp from the Date and Time keys.
DW queries are all about not having any functions in the WHERE clause, or if a function has to be used, make sure it is SARGABLE.
You would probably be better served by converting the Start Date and End Date columns to TIMESTAMP and populating them.
Slicing the table would require taking the appropriate interval BETWEEN Start Date AND End Date. In Oracle the interval would be something along the lines of SYSDATE - (4/24) or SYSDATE - NUMTODSINTERVAL(4, 'HOUR')
This could also be rewritten as:
Start Date <= (SYSDATE - (4/24)) AND End Date >= (SYSDATE - (4/24))
It seems to me that given the current schema you have, that you will need to retrieve the appropriate time IDs from the time dimension table which meet your search criteria, and then search for matching rows in the fact table. Depending on the granularity of your time dimension, you might want to check the performance of doing either (SQL Server examples):
A subselect:
SELECT X FROM FOO WHERE TIMEID IN (SELECT ID FROM DIMTIME WHERE HOUR >= DATEPART(HOUR, CURRENT_TIMESTAMP()) AND DATEID IN (SELECT ID FROM DIMDATE WHERE DATE = GETDATE())
An inner join:
SELECT X FROM FOO INNER JOIN DIMTIME ON TIMEID = DIMTIME.ID WHERE HOUR >= DATEPART(HOUR, CURRENT_TIMESTAMP()) INNER JOIN DIMDATE ON DATEID = DIMDATE.ID WHERE DATE = GETDATE()
Neither of these are truly attractive options.
Have you considered that you may be querying against a cube that is intended for roll-up analysis and not necessarily for "last X" analysis?
If this is not a "roll-up" cube, I would agree with the other posters in that you should re-stamp your fact tables with better keys, and if you do in fact intend to search off of hour frequently, you should probably include that in the fact table as well, as any other attempt will probably make the query non-sargable (see What makes a SQL statement sargable?).
Microsoft recommends at http://msdn.microsoft.com/en-us/library/aa902672%28v=sql.80%29.aspx that:
In contrast to surrogate keys used in other dimension tables, date and time dimension keys should be "smart." A suggested key for a date dimension is of the form "yyyymmdd". This format is easy for users to remember and incorporate into queries. It is also a recommended surrogate key format for fact tables that are partitioned into multiple tables by date.
Best luck!

Insert a datetime value with GetDate() function to a SQL server (2005) table?

I am working (or fixing bugs) on an application which was developed in VS 2005 C#. The application saves data to a SQL server 2005. One of insert SQL statement tries to insert a time-stamp value to a field with GetDate() TSQL function as date time value.
Insert into table1 (field1, ... fieldDt) values ('value1', ... GetDate());
The reason to use GetDate() function is that the SQL server may be at a remove site, and the date time may be in a difference time zone. Therefore, GetDate() will always get a date from the server. As the function can be verified in SQL Management Studio, this is what I get:
SELECT GetDate(), LEN(GetDate());
-- 2010-06-10 14:04:48.293 19
One thing I realize is that the length is not up to the milliseconds, i.e., 19 is actually for '2010-06-10 14:04:48'. Anyway, the issue I have right now is that after the insert, the fieldDt actually has a date time value up to minutes, for example, '2010-06-10 14:04:00'. I am not sure why. I don't have permission to update or change the table with a trigger to update the field.
My question is that how I can use a INSERT T-SQL to add a new row with a date time value ( SQL server's local date time) with a precision up to milliseconds?
Check your table. My guess is that the FieldDT column has a data type of SmallDateTime which stores date and time, but with a precision to the nearest minute. If my guess is correct, you will not be able to store seconds or milliseconds unless you change the data type of the column.
I would guess that you are not storing the GetDate() value in a DateTime field. If you store the value in a datetime field you will get the maximum precision allowed by the DateTime type. Additionally, DateTime is a binary type (a double actually) so 19 means 19 bytes, not 19 characters.
Try to create a simple table with a Datetime field like this
CREATE TABLE [dbo].[DateTable](
[DateField] [datetime] NOT NULL
)
And add a date with
insert into datetable (datefield) values(getdate())
When you execute a select you will get back a value including milliseconds. The following query
select * from datetable
returns
2010-06-11 00:38:46.660
Maybe this would work instead of getdate -
SYSDATETIME()
look here if you can find what you need -
http://msdn.microsoft.com/en-us/library/ms188383.aspx
As you're on SQL 2005, don't forget the getutcdate() function to ensure that, regardless of where your servers are actually located, you have a constant time reference.
Imagine, you have the server in the UK in winter (i.e. GMT+0), and save a record at 10:30am. You then cut over to a SQL server hosted in California (GMT+8) and 8 hours later save another record.
Using getdate(), both saves record the same time "10:30:00". Using getutcdate(), the first save records at "10:30:00", the second save records "18:30:00".
Not really answering the question, but important in your circumstances.
You can use like this in procedure and If there is no procedure use only getdate().
insert into [dbo].[Tbl_User] (UserId,Uvendoremail,UAddress,Ddob,DMobile,
DEmail,DPassword,DAddress,CreatedDate) values (#userid,#vendoremail#address,#dob,#mobile,#email,#dpassword,#daddress,getdate())

Resources