How to create a table that allows a user to type a time value only [duplicate] - sql

In one field I need to store not a datetime pair, i.e. a standard Oracle date.
01/10/2009 22:10:39
But time only
22:10:39
I think that save disk space (I have 2 million rows) or provide faster processing.

You could try the INTERVAL DAY TO SECOND data type but it won't save you any disk space ... it is very suitable for this purpose though.
create table t1 (time_of_day interval day (0) to second(0));
insert into t1 values (TO_DSINTERVAL('0 23:59:59'));
select date '2009-05-13'+time_of_day
from t1;
11 bytes though.

Your best bet would probably be storing "seconds since midnight" as a number field.
SELECT to_char( SYSDATE, 'SSSSS' ) FROM dual;

You can extract the time from a date as a string like this:
to_char(sysdate,'HH.MI.SS')
but there is no time-only data type that will help you save space.

you can use:
TO_CHAR(<DATE_COLUMN>, '<TIME_FORMAT>');
example
TO_CHAR(SYSDATE, 'HH24:MI:SS');
for time format you can check in here

You would save a few Mb of disk space(which is nothing nowadays) and you would gain next to nothing in performance.
You could use a column of NUMBER type for storing the number of seconds since midnight as suggested, just don't forget about the constraints.
(You'd probably use NUMBER(5, 0) which uses 1-3 bytes depending on the stored value, instead of a constant 7 bytes used by a DATE column)

Related

How to insert only hour and minute into table?

Tried this:
INSERT INTO Airplanes
VALUES (1, 'Boeing 720-020', 'New York', TO_DATE('17:30', 'HH24:MI'), 219);
But after running it, in the table I have 10/01/2018 instead of 17:30.
I'm really grateful for your help.
DATE in Oracle is actually a datetime datatype. There is no TIME datatype. So if you want to store a time only then you need to use a string.
create table airplane (
id number primary key
, plane_type varchar2(32) not null
, destination varchar2(32) not null
, flight_time varchar2(5) not null check (regexp_like(flight_time, '[0-9]{2}:[0-9]{2}'))
)
/
The check constraint enforces a format of 99:99. You can make if stricter if you wish.
I have some sympathy with #AlexPoole that we should use a DATE column to store a time, because it does make it easier to ensure that only valid times are entered. But then we have to restrict the date part to make sure it is always the same magic date and we always have to apply a format mask whenever we query the table to make sure it only displays the time. So we gain something but we also lose something.
There are more baroque solutions. You could define flight_time as an interval:
, flight_time interval day to second
Then your insert statement would be
insert into airplane
values (1, 'Boeing 720-020','New York',INTERVAL '0 17:30:0' DAY TO SECOND);
You'd still want a check that the DAY element was zero. And I think the queried output would still need formatting.
But I suspect we're starting to over-engineer what appears to be a course assignment. So stick with the string unless you need something better,
You can try using to_char function.
Example:
SELECT TO_CHAR(SYSDATE,'HH24:MI') FROM DUAL;
You can store time as what you've shown:
TO_DATE('17:30', 'HH24:MI')
Your table Airplanes has a column of date data type (which is actually date and time as stated by APC) where you tried to store that time. Your time is indeed stored but it comes with a date that you did not specify and defaulted to the first day of the current month.
Your only problem is that Oracle showed you the date when you selected it. So, to get over with that, just use to_char() to only display the time in a particular format, like so:
select to_char(column_name,'HH24:MI') from Airplanes;
If you'd go down this road, let me suggest to store also the date of that time so you won't end up with useless dates in your records. So if, for example, you're storing the flight time, also store the date of the flight on that same column, like so:
TO_DATE('2018-10-17 17:30', 'YYYY-MM-DD HH24:MI')
Also, use the date data type so that you can take advantage of the built-in date/time functions like easily displaying the time in a particular format.

How to have a table column with only minutes and seconds

I have a database project that I have to insert some music information in it. In one of my tables, I have a column in which I have to insert the track time of all the songs. For that, I was wondering if there is any function (similar to to_date()) that I can use in order to insert minute:second format only.
I tried to use to_timestamp(). However, it will always give me actual date with the first day of the month that I insert the data.
for example:
to_timestamp('9:10','MI:SS')
Result:
18-06-01, 00:9:10,0000000
PS: for the track time column, is it ok to defined the datatype as TIMESTAMP?
Oracle doesn't support a separate time data type.
I would suggest that you store the value as a number of seconds if you want to do arithmetic (such as adding up the values). If you just want to look at them, use a string format.
If you want to convert a number of seconds to minutes/seconds, you can use:
select floor(secs / 60) || ':' || lpad(mod(secs, 60), 2, '0')

store duration in teradata

I am getting source data with duration between 2 timestamps as
Duration Start date End date Start station
14h 26min. 2sec. 12/31/2010 23:49 1/1/2011 14:15 10th & U St NW (31111)
how can I import this data ( which is in CSV file ) in Teradata database to store duration in correct data type, so that I can match it properly with the difference between start and end data?
Please help in correct approach here.
Thanks in advance
That's quite tricky.
A pure SQL based solution (without features of your ETL-tool) needs to generate data which can be safely casted.
This will modify your duration into a format which can be passed to to_dsinterval by removing unneccessary characters besides HMS (target column should be defined as INTERVAL HOUR(4) TO SECOND(0))
Cast(to_dsinterval('PT'||Upper(OTranslate(duration, ' in.ec', ''))) AS INTERVAL HOUR(4) TO SECOND(0))
Your input timestamps show single digit day/month, which Teradata doesn't support (don't aks why), the RegEx adds those missing zeroes (when the seconds are missing remove the :ss part of the format):
Cast(RegExp_Replace(start_date, '\b([0-9])\b', '0\1') AS TIMESTAMP(0) Format 'mm/dd/yyyyBhh:mi:ss')
Finally pass duration & timestamps as VarChars and apply the Casts during Insert.

SQL Server DateTime2(0) vs Date

What are the implications of using SQL Server's DateTime2 with a precision of 0 to represent a date rather than the built in Date field.
In either case, my concern is to prevent accidental time entries, but are there storage or performance considerations I should take note of?
DateTime2(0) will store datetime with no decimal values i.e YYYY-MM-DD hh:mm:ss
SELECT CONVERT(DateTime2(0) , GETDATE())
RESULT: 2015-04-06 20:47:17
Storing data just as dates will only store dates i.e YYYY-MM-DD without any time values.
SELECT CONVERT(Date , GETDATE())
RESULT: 2015-04-06
If you are only interested in dates then use DATE data type.
DATETIME2 will use 6 bytes for precisions less than 3 and DATE will use 3 bytes.
Date is half the size of DATETIME(0) hence it will also perform better since sql server will process less data and will save disk space as well.
It won't work. According to MSDN the minimum size of Datetime2 is six bytes and will contain hh:mm:ss so it can, and will, contain a time component (default of midnight). As other responders have noted you must use a date type to guarantee that not time portion is saved and will occupy three bytes.
https://technet.microsoft.com/en-us/library/bb677335%28v=sql.105%29.aspx
Just a reminder which I ran into myself when I converted a couple of DATETIME2(0) columns to DATE to make sure it aligned better with the value in the column (date only).
When using DATE you cannot use things like SELECT MyDate + 1 FROM.. or WHERE MyDate>0 while when using DATETIME2 you can, at least not in MS-SQL. Ofcourse IMHO it doesn't make any sense why DATETIME2 will allow you to do it and DATE not.

How to update dates stored as varying character formats (PL/SQL)?

Problem: I have a large database table (~500k records) which has a list of dates stored in a varchar2(15) column. These dates are stored in varying formats, ie. some are yyyy-mm-dd, some are mm/dd/yyyy, some are dd/mm/yy, some are mm/dd/yy, etc. Ie:
1994-01-13
01/13/1994
01/13/94
13/01/94
13/01/1994
etc
I need to be able to shift these dates slightly, for example to add 30 days to each date. (This is an oversimplification of my objective but it's easier to explain this way).
If all the dates were formatted consistently, I would achieve this as follows:
UPDATE history_table
SET some_date_col =
to_char(to_date(some_date_col, 'mm/dd/yyyy')+30, 'mm/dd/yyyy')
WHERE some_date_col IS NOT NULL;
Due to the size of the database, I cannot afford to loop through the values one by one and parse the date value. Can anyone suggest a means to accomplish this without loops, ie with a mass UPDATE statement?
Are the formats of these dates really that important? They should be datetime columns. Then you could just use date math functions on that field.
well, you've got a real problem here.
07/07/1994 is valid for 'MM/DD/YYYY' and 'DD/MM/YYYY'
However, outside of that issue, you can try nesting decodes.
I entered the following dates into a varchar field:
01/12/2009, 01-12-2009, 2009-01-12, 01/12/09
and using the below, I was consistently returned 1/12/2009. You'll have to figure out all the patterns possible and keep nesting decodes. The other thing you could do is create a function to handle this. Within the function, you can check with a little more detail as to the format of the date. It will also be easier to read. You can use the function in your update statement so that should be faster than looping through, as you mentioned.
(for what its worth, looping through 500k rows like this shouldn't take very long. I regularly have to update row by row tables of 12 million records)
select mydate,
decode(instr(mydate,'-'),5,to_date(mydate,'YYYY-MM-DD'),3,to_date(mydate,'MM-DD-YYYY'),
decode (length(mydate),8,to_date(mydate,'MM/DD/YY'),10,to_date(mydate,'MM/DD/YYYY')))
from mydates;
and here is the update statement:
update mydates set revdate = decode(instr(mydate,'-'),5,to_date(mydate,'YYYY-MM-DD'),3,to_date(mydate,'MM-DD-YYYY'),
decode (length(mydate),8,to_date(mydate,'MM/DD/YY'),10,to_date(mydate,'MM/DD/YYYY')))
IMHO, you have a bigger problem:
If some dates are dd/mm/yyyy and some are mm/dd/yyyy how can you difference which format applies for certain date?
for example, how can I know if a value "12/09/2008" means December or September?