Adding time to a table in SQLplus without date - sql

I am trying to create a table regarding telecommunication and I want to add time for 2 rows call_start_time and call_end_time and with that, I want to calculate the call_duration.
This is what I used to enter the value
to_date('2021/05/31:20:20:20','yyyy/mm/dd hh24:mi:ss')
If I use this format while displaying the data only the date is displayed not the time.
Can someone help me create a table where I just have to input the time alone not the date and calculate the call_duration using call_start_time and call_end_time?
Heres the table I created:
SQL> create table MOBILE_TRANSACTION (
mob_no number(10),
call_type varchar2(25),
call_category varchar2(25),
call_start_time date,
call_end_time date,
call_duration number,
call_charges_rs number );
I hope my question is clear.

[TL;DR] You don't need to create a time column as the DATE column already has a time but SQL/Plus it not showing it; chage the settings on SQL/Plus and use what you already have.
Your table has a time component; the user interface (SQL/Plus) is chosing not to display it.
If you want to change the default display format then use:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
Then:
SELECT *
FROM MOBILE_TRANSACTION;
If you want to explicitly convert the date to have a format (since it is stored as a binary value and has no format in the database and it is only when it reaches the user interface you are using that that user interface converts the binary to something human readable) then you can use TO_CHAR:
SELECT mob_no,
call_type,
call_category,
TO_CHAR(call_start_time, 'YYYY-MM-DD HH24:MI:SS') AS call_start_time,
TO_CHAR(call_end_time, 'YYYY-MM-DD HH24:MI:SS') AS call_end_time,
call_duration,
call_charges_rs
FROM MOBILE_TRANSACTION
If you want to calculate the duration then you can use a virtual column:
create table MOBILE_TRANSACTION (
mob_no number(10),
call_type varchar2(25),
call_category varchar2(25),
call_start_time date,
call_end_time date,
call_duration INTERVAL DAY TO SECOND
GENERATED ALWAYS AS (
(call_end_time - call_start_time) DAY TO SECOND
),
call_charges_rs number
);
db<>fiddle here
or
create table MOBILE_TRANSACTION (
mob_no number(10),
call_type varchar2(25),
call_category varchar2(25),
call_start_time date,
call_end_time date,
call_duration number
GENERATED ALWAYS AS ((call_end_time - call_start_time) * 24 * 60 * 60),
call_charges_rs number
);
db<>fiddle here

Related

How to split a datetime column in to two columns of Date and time separately in Oracle SQL?

I have a datetime column.
I want two columns: a date and a time column.
How can I split my column into two?
Use:
a DATE data-type with the time component set to midnight for the date (you can enforce this with a check constraint); and
an INTERVAL DAY(0) TO SECOND data-type for the time component.
CREATE TABLE table_name(
datetime_column DATE,
date_column DATE,
time_column INTERVAL DAY(0) TO SECOND,
CONSTRAINT table_name__date_column__chk CHECK (date_column = TRUNC(date_column))
)
If you want to get the combined date-time then you can easily add the two to get back to a date-time value.
How can I split my column into two?
Assuming you have the columns you can use:
UPDATE table_name
SET date_column = TRUNC(datetime_column),
time_column = (datetime_column - TRUNC(datetime_column)) DAY TO SECOND;
db<>fiddle here
As Gordon commented, there's no time datatype in Oracle.
Though, literally answering what you asked, you can separate date and time and store each of them into their own columns - it's just that these will be VARCHAR2 columns and you can only look at how pretty they are. You can't, for example, do any date arithmetic on them; first you'd have to convert them back to date datatype, so question is what you really want to do with what you get.
Anyway, here you are:
SQL> create table test
2 (datum date,
3 date_only varchar2(10),
4 time_only varchar2(8)
5 );
Table created.
Sample value:
SQL> insert into test (datum) values (sysdate);
1 row created.
Split date to two parts:
SQL> update test set
2 date_only = to_char(datum, 'dd.mm.yyyy'),
3 time_only = to_char(datum, 'hh24:mi:ss');
1 row updated.
What's in there?
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select * from test;
DATUM DATE_ONLY TIME_ONL
------------------- ---------- --------
05.08.2021 21:05:06 05.08.2021 21:05:06
SQL>
Since there is no specific datatype for time, here my suggestion would be to keep the datetime in main column and add two VIRTUAL COLUMN for date value and time value respectively.
Oracle 11g has introduced a new feature that allows you to create a VIRTUAL COLUMN, an empty column that contains a function upon other table columns (the function itself is stored in the data dictionary).
However, it all depends on what you are going to do with it.
Please elaborate your requirement so that you will get a more specific answer.

how to embed a function to column in PostgreSQL

I'm new to SQL and PostgreSQL and I'm trying to find a way to create a new table in database where a column will automatically calculate a pre-defined function with data from other columns.
Specifically I want a LOG table with
TIME_IN | TIME_OUT | DURATION columns
where the DURATION column shows the result of (=TIME_OUT - TIME_IN)
Of course this can be done with running a query but I'm trying to figure out if it's possible
to have it pre-defined so whenever running SELECT * FROM log
the table will load up with duration value already calculated according to updated data in IN / OUT columns.
This can be done using a generated column, e.g.:
create table log
(
id integer primary key generated always as identity,
time_in timestamp,
time_out timestamp,
duration interval generated always as (time_out - time_in) stored
);
Another option would be to create a view:
create view log_with_duration
as
select id,
time_in,
time_out,
time_out - time_in as duration
from log;

How do i get an age according to the current system time in NLS_DATE_FORMAT? (Oracle SQL)

I have a table called person, how do i get a person age according to the current system time in NLS_DATE_FORMAT?
ALTER SESSION SET NLS_DATE_FORMAT = 'DD.MM.YYYY';
CREATE TABLE person (
person_id NUMBER (9),
birthday DATE CONSTRAINT nn_person_birthday NOT NULL,
...
);
Note: I just want the exact age, not months neither days. Example Age: 43
Note2: I insert birthday like this in my table: TO_DATE('17.05.2003','DD.MM.YYYY')
The date format doesn't matter. I would suggest:
floor(months_between(sysdate, p.birthday) / 12)

SQL Trigger calculating difference for timestamps

I cannot seem to find a solution on calculating time difference, using trigger for automatically generating duration into my table when inserting two timestamps.
Here is my table 'call':
create table call(
id varchar(5),
start_time timestamp,
end_time timestamp,
duration INTERVAL DAY(3) TO SECOND (4),
primary key(id));
I am trying to use a trigger
create sequence time_diff;
CREATE OR REPLACE TRIGGER DURATION
BEFORE INSERT ON call
for each row
BEGIN
begin select time_diff //confused and don't know what to do
END;
I am hoping doing insertion like this would work
insert into call values(111,'2015-04-21 15:42:23','2016-11-03 18:32:47',null);
and my timestamp format is 'YYYY-MM-DD HH24:MI:SS';
A few things: First, why are you storing a calculated number? Violating normal form. At the very least, make it a virtual column. Second, you can't enter timestamps like that; use the proper syntax for timestamps. (If you don't know what it is, type "Oracle timestamp literal" in Google.) Third, is your question how to compute the difference between two timestamps, in seconds? The difference between timestamps is an "interval day to second"; you can extract day, hour, minute and second from it (separately), and convert everything to seconds. As in, tsdiff := timestamp_1 - timestamp_2, and then diff_seconds := extract (day from tsdiff) * 86400 + extract(hour from tsdiff) * 3600 + ...

Oracle — separate time and date

I have a question with Oracle (I've installed Oracle 11g Express Edition).
I want to insert values for 'date' and 'time', but I cannot separate them.
create table Match
(
numMatch number(2) constraint PKMatch primary key,
dateM date,
heureM date,
numE_Eq number(2),
numE_Eq2 number(2),
nomTerrain varchar2(30)
);
--"tools"=>"preferences"=>"format de date:DD/MM/YYYY HH24:MI:SS"
insert into Match values (1,to_date
('10/12/2010','DD/MM/YYYY'),to_date('15:00:00','HH24:MI:SS'),1,3,'Stade Argentina'
);
result:
dateM: 10/12/2010 00:00:00
heureM: 01/11/2012 15:00:00
PS: I've tried to_char instead of to_date, but it didn't work at all.
Yes, I'm aware of that 'DATE datatype contains both date and time', but it's the prof who insists showing date and time separately in the table,
and I've seen your solutions before, but for me, it's a query, not to 'insert values' in the table.
So I'd like to know how I can have a table directly presenting date and time.
Oracle doesn't have a TIME datatype. You can store a DATE with a time component, and just query based on time, and display based on time.
select to_char(my_date_field, 'HH24:MI:SS')
from my_table
where to_date(my_date_field, 'HH24:MI') = '18:51';
Alternatively, you can store seconds from midnight as an integer, and calculate the time of day from that. It will also make querying for range times easier I think.
Also, within a session, execute the following to have all dates formatted the way you wish:
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'
Another way to represent a TIME equivalent type in Oracle is with the INTERVAL type, such as:
SQL> CREATE TABLE foo (
bar INTERVAL DAY(0) TO SECOND(3)
);
This would allow the storage of a time period with 0 precision of the DAY component, and 3 decimal points for the SECOND component. An INSERT example is:
SQL> INSERT INTO foo VALUES ('0 01:01:01.333');
What's great about this approach is that it automatically presents the results of a SELECT in an intuitive format without the need for conversion:
SQL> SELECT * FROM foo;
BAR
---------------------------------------------------------------------------
+0 01:01:01.333
but it's the prof who insists showing date and time separately in the table
While this sounds like a pretty stupid requirement, one thing you could do is to create two computed columns that show the date and time as varchar columns:
create table match
(
nummatch number(2) constraint pkmatch primary key,
the_date date,
datem generated always as to_char(the_date, 'yyyy-mm-dd'),
heurem generated always as to_char(the_date, 'hh24:mi')
nume_eq number(2),
nume_eq2 number(2),
nomterrain varchar2(30)
);
insert into Match (nummatch, the_date, nume_eq, nume_eq2, nomterrain)
values
(1,to_date('10/12/2010 15:00:00','DD/MM/YYYY hh24:mi:ss'),1,3,'Stade Argentina');
Then a
select *
from match;
will return:
NUMMATCH | THE_DATE | DATEM | HEUREM | NUME_EQ | NUME_EQ2 | NOMTERRAIN
---------+---------------------+------------+--------+---------+----------+----------------
1 | 2010-12-10 15:00:00 | 2010-12-10 | 15:00 | 1 | 3 | Stade Argentina
Alternatively you could just create a view on the table that separates the date and time using to_char()
Oracle DATE type includes both DATE and TIME information (because it pre-dates the SQL-92 standard when the standard DATE, TIME and TIMESTAMP types were added). So, you can't separate them in the table; there's no reason to do so, either. You can, if you so desire, create a view which presents the DATE field as separate date-only and time-only display fields.