Column with exact date and time of recording - sql

How to Add to a Database Table the Exact Date and Time, Adding a New Record to this Table
SELECT * FROM test;
ID NAME DT
---------- ---------- ----------
1 Ana 01.01.2019 00:00:00
2 Ina 01.01.2019 00:00:00
I want the exact time when this one was created
example:
ID NAME DT
---------- ---------- ----------
1 Ana 01.01.2019 10:41:22
2 Ina 01.01.2019 10:45:17
CREATE TABLE table
(
Id NUMBER(10),
Name varcahar2(10),
DT date
);

CREATE TABLE test
(
Id NUMBER(10),
Name varchar2(10),
DT date
);
Insert data:
INSERT INTO test values (1, 'Ana', sysdate);
INSERT INTO test values (2, 'Ina', sysdate);
COMMIT;
Query results:
SELECT id, name, TO_CHAR(dt, 'dd.mm.yyyy hh24:mi:ss') FROM test;
ID NAME TO_CHAR(DT,'DD.MM.Y
---------- ---------- -------------------
1 Ana 02.09.2019 10:07:18
2 Ina 02.09.2019 10:07:18

Oracle Setup:
CREATE TABLE table_name(
Id NUMBER(10),
Name VARCHAR2(10),
DT DATE
);
Option 1:
Use a DATE and INTERVAL literals:
INSERT INTO table_name ( id, name, dt )
VALUES ( 1, 'Ana', DATE '2019-01-01' + INTERVAL '10:41:22' HOUR TO SECOND );
Option 2:
Use TO_DATE and convert from a string:
INSERT INTO table_name ( id, name, dt )
VALUES ( 2, 'Ina', TO_DATE( '2019-01-01 10:45:17', 'YYYY-MM-DD HH24:MI:SS' ) );
Option 3:
Use a TIMESTAMP literal:
INSERT INTO table_name ( id, name, dt )
VALUES ( 3, 'Ona', TIMESTAMP '2019-01-01 10:49:12' );
Option 4:
If you want the current date & time then use SYSDATE:
INSERT INTO table_name ( id, name, dt )
VALUES ( 4, 'Una', SYSDATE );
or CURRENT_DATE:
INSERT INTO table_name ( id, name, dt )
VALUES ( 4, 'Una', CURRENT_DATE );
Output:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
SELECT * FROM table_name;
or
SELECT id, name, TO_CHAR( dt, 'YYYY-MM-DD HH24:MI:SS' ) AS dt FROM table_name;
Outputs:
ID | NAME | DT
-: | :--- | :------------------
1 | Ana | 2019-01-01 10:41:22
2 | Ina | 2019-01-01 10:45:17
3 | Ona | 2019-01-01 10:49:12
4 | Una | 2019-09-02 09:22:28
db<>fiddle here

use TIMESTAMP
CREATE TABLE table
(
Id NUMBER(10),
Name varchar2(10),
DT TIMESTAMP
);

Insert current date with your data, and use analytical function to compare time since last event.
CREATE TABLE so_test
(
Id NUMBER(10),
Name varchar2(10),
DT date
);
insert into so_test values (1, 'Scott', sysdate);
insert into so_test values (2, 'Andrii', sysdate);
insert into so_test values (3, 'Zaynul', sysdate);
select id, name, dt
,round((dt-LAG(dt) OVER (ORDER BY id))*86400) seconds_diff
from so_test
ID NAME DT SECONDS_DIFF
---------- ---------- ------------------- ------------
1 Scott 02-09-2019 16:02:47
2 Andrii 02-09-2019 16:02:58 11
3 Zaynul 02-09-2019 16:03:12 14

Related

How to add a column that contains the next date column with SQL oracle developper

I want to add a column to my table that contains the next Birthdate (ordered by Birthdate)
This is my actuale table:
ID
Birthdate
Personne1
19/11/90 19:14:52,182000000
Personne1
19/11/90 20:00:52,170000000
Personne1
19/11/90 21:00:00,190000000
And I'm looking for this table
ID
Birthdate
nextdate
Personne1
19/11/94 90:14:52,182000000
90/11/94 20:00:52,170000000
Personne1
19/11/94 90:00:52,170000000
90/11/94 21:00:00,190000000
Personne1
19/11/94 90:00:00,190000000
N/A
Is there any function like 'NEXT(Birthdate)' ? in order to calculate the difference in min:ss between the Birthdate column and the next_Birthday column
That would be LEAD analytic function.
Sample data:
SQL> with test (id, birthdate) as
2 (select 'personne1', to_timestamp('19.11.1990 19:14:52,182000000', 'dd.mm.yyyy hh24:mi:ss,ff9') from dual union all
3 select 'personne1', to_timestamp('19.11.1990 20:00:52,170000000', 'dd.mm.yyyy hh24:mi:ss,ff9') from dual union all
4 select 'personne1', to_timestamp('19.11.1990 21:14:00,190000000', 'dd.mm.yyyy hh24:mi:ss,ff9') from dual
5 ),
As you want to calculate something based on those values, use extract function which works well on timestamps (which is what you, apparently, have):
6 temp as
7 (select id,
8 birthdate,
9 lead(birthdate) over (partition by id order by birthdate) nextdate
10 from test
11 )
12 select id, birthdate, nextdate,
13 extract(minute from (nextdate - birthdate)) mins,
14 extract(second from (nextdate - birthdate)) secs
15 from temp;
ID BIRTHDATE NEXTDATE MINS SECS
--------- ------------------------------ ------------------------------ ---------- ----------
personne1 19.11.90 19:14:52,182000000 19.11.90 20:00:52,170000000 45 59,988
personne1 19.11.90 20:00:52,170000000 19.11.90 21:14:00,190000000 13 8,02
personne1 19.11.90 21:14:00,190000000
SQL>

postgresql How show most frequent value per day date

I've got a problem with a query that is supposed to return the value which occur most per date
+------------+------------------+
| Date | value |
+------------+------------------+
| 2020-01-01 | Programmer |
| 2020-01-02 | Technician |
| 2020-01-03 | Business Analyst |
+------------+------------------+
So far I have done
select count(headline) as asd, publication_date, employer -> 'name' as dsa from jobhunter
group by publication_date,dsa
ORDER BY publication_date DESC
But it shows 2020-12-31 19:06:00 instead of just YYYY-MM-DD
Any idea on how to fix this?
enter image description here
Test data:
create table tbl (
id serial primary key,
row_datetime TIMESTAMP,
row_val VARCHAR(60)
);
insert into tbl (row_datetime, row_val) values ('2021-01-01 00:00:00', 'a');
insert into tbl (row_datetime, row_val) values ('2021-01-01 01:00:00', 'a');
insert into tbl (row_datetime, row_val) values ('2021-01-01 02:00:00', 'b');
insert into tbl (row_datetime, row_val) values ('2021-01-02 00:00:00', 'a');
insert into tbl (row_datetime, row_val) values ('2021-01-02 01:00:00', 'b');
insert into tbl (row_datetime, row_val) values ('2021-01-02 02:00:00', 'b');
Example query:
SELECT dt, val, cnt
FROM (
SELECT dt, val, cnt, ROW_NUMBER() OVER (PARTITION BY dt ORDER BY cnt DESC) AS row_num
FROM (
SELECT dt, val, COUNT(val) AS cnt
FROM (
SELECT DATE(row_datetime) AS dt, row_val AS val FROM tbl
) AS T1 GROUP BY dt, val
) AS T2
) AS T3
WHERE row_num=1
ORDER BY dt ASC
You can additionally customize your query to optimize the performance, get more fields, etc.

List of dates between two tables in oracle

Problem
Input:
START_DATE END_DATE
01-FEB-16 03-FEB-16
01-FEB-16 02-FEB-16
10-FEB-16 11-FEB-16
I want to generate all the dates between the start_day and end_day as
Output
01-FEB-16
02-FEB-16
03-FEB-16
10-FEB-16
11-FEB-16
You could do it using Row Generator technique.
Setup
SQL> CREATE TABLE t
2 (START_DATE DATE, END_DATE DATE
3 );
Table created.
SQL> INSERT INTO t VALUES(DATE '2016-02-01', DATE '2016-02-03');
1 row created.
SQL> INSERT INTO t VALUES(DATE '2016-02-01', DATE '2016-02-02');
1 row created.
SQL> INSERT INTO t VALUES(DATE '2016-02-10', DATE '2016-02-11');
1 row created.
SQL> COMMIT;
Commit complete.
Query
SQL> SELECT DISTINCT TO_CHAR(START_DATE+LEVEL-1, 'DD-MON-YYYY') the_date
2 FROM t
3 CONNECT BY LEVEL <= END_DATE-START_DATE+1
4 ORDER BY the_date
5 /
THE_DATE
-----------
01-FEB-2016
02-FEB-2016
03-FEB-2016
10-FEB-2016
11-FEB-2016
SQL>

Analytical function range window for max date interval

I am trying to get 10 minute interval data from latest date of each group or partition.
Pseudo code SQL:
Select
count(1) Over( partition by col1, col2, col3
Order by Col_Date Desc
Range Max(Col_Date) Between Max(Col_Date) - 10(24*60) ) col_upd
From
Table_1;
Values out of of this particular range will have need assign number to set for delete.
2014-01-05 01:20:00 -- Max date
2014-01-05 01:15:13
2014-01-05 01:12:13
2014-01-05 01:07:13 -- 1) these last two rows should be set for
2014-01-05 01:06:13 -- 2) delete or assign same id
Is there any analytical function way to approach this?
You haven't given table structures, but if I make up a dummy table like:
create table t42 (id number, grp_id number, dt date);
insert into t42 values (1, 1, timestamp '2014-01-05 01:20:00');
insert into t42 values (2, 1, timestamp '2014-01-05 01:15:13');
insert into t42 values (3, 1, timestamp '2014-01-05 01:12:13');
insert into t42 values (4, 1, timestamp '2014-01-05 01:07:13');
insert into t42 values (5, 1, timestamp '2014-01-05 01:06:13');
Then this will give you the age of each row in the group compared to its (analytic) max:
select grp_id, id, dt, max(dt) over (partition by grp_id) - dt as age
from t42
order by id;
GRP_ID ID DT AGE
---------- ---------- ------------------- ------------
1 1 2014-01-05 01:20:00 0
1 2 2014-01-05 01:15:13 .00332175926
1 3 2014-01-05 01:12:13 .00540509259
1 4 2014-01-05 01:07:13 .00887731481
1 5 2014-01-05 01:06:13 .00957175926
And you can use that as an inner query and filter out records up to 10 minutes old:
select grp_id, id, dt
from (
select grp_id, id, dt, max(dt) over (partition by grp_id) - dt as age
from t42
)
where age > (10*60)/(24*60*60)
order by id;
GRP_ID ID DT
---------- ---------- -------------------
1 4 2014-01-05 01:07:13
1 5 2014-01-05 01:06:13
And you can then use those up delete/update as needed. It's not clear from your question if your group/partition is already being calculated from an inner query; if so you can just use that instead of my t42 table. (Changing column names etc., of course).

Finding a 'run' of rows from an ordered result set

I'm trying to figure out a way of identifying a "run" of results (successive rows, in order) that meet some condition. Currently, I'm ordering a result set, and scanning by eye for particular patterns. Here's an example:
SELECT the_date, name
FROM orders
WHERE
the_date BETWEEN
to_date('2013-09-18',..) AND
to_date('2013-09-22', ..)
ORDER BY the_date
--------------------------------------
the_date | name
--------------------------------------
2013-09-18 00:00:01 | John
--------------------------------------
2013-09-19 00:00:01 | James
--------------------------------------
2013-09-20 00:00:01 | John
--------------------------------------
2013-09-20 00:00:02 | John
--------------------------------------
2013-09-20 00:00:03 | John
--------------------------------------
2013-09-20 00:00:04 | John
--------------------------------------
2013-09-21 16:00:01 | Jennifer
--------------------------------------
What I want to extract from this result set is all the rows attributed to John on 2013-09-20. Generally what I'm looking for is a run of results from the same name, in a row, >= 3. I'm using Oracle 11, but I'm interested to know if this can be achieved with strict SQL, or if some kind of analytical function must be used.
You need multiple nested window functions:
SELECT *
FROM
(
SELECT the_date, name, grp,
COUNT(*) OVER (PARTITION BY grp) AS cnt
FROM
(
SELECT the_date, name,
SUM(flag) OVER (ORDER BY the_date) AS grp
FROM
(
SELECT the_date, name,
CASE WHEN LAG(name) OVER (ORDER BY the_date) = name THEN 0 ELSE 1 END AS flag
FROM orders
WHERE
the_date BETWEEN
TO_DATE('2013-09-18',..) AND
TO_DATE('2013-09-22', ..)
) dt
) dt
) dt
WHERE cnt >= 3
ORDER BY the_date
Try this
WITH ORDERS
AS (SELECT
TO_DATE ( '2013-09-18 00:00:01',
'YYYY-MM-DD HH24:MI:SS' )
AS THE_DATE,
'John' AS NAME
FROM
DUAL
UNION ALL
SELECT
TO_DATE ( '2013-09-19 00:00:01',
'YYYY-MM-DD HH24:MI:SS' )
AS THE_DATE,
'James' AS NAME
FROM
DUAL
UNION ALL
SELECT
TO_DATE ( '2013-09-20 00:00:01',
'YYYY-MM-DD HH24:MI:SS' )
AS THE_DATE,
'John' AS NAME
FROM
DUAL
UNION ALL
SELECT
TO_DATE ( '2013-09-20 00:00:02',
'YYYY-MM-DD HH24:MI:SS' )
AS THE_DATE,
'John' AS NAME
FROM
DUAL
UNION ALL
SELECT
TO_DATE ( '2013-09-20 00:00:03',
'YYYY-MM-DD HH24:MI:SS' )
AS THE_DATE,
'John' AS NAME
FROM
DUAL
UNION ALL
SELECT
TO_DATE ( '2013-09-20 00:00:04',
'YYYY-MM-DD HH24:MI:SS' )
AS THE_DATE,
'John' AS NAME
FROM
DUAL
UNION ALL
SELECT
TO_DATE ( '2013-09-21 16:00:01',
'YYYY-MM-DD HH24:MI:SS' )
AS THE_DATE,
'Jennifer' AS NAME
FROM
DUAL)
SELECT
B.*
FROM
(SELECT
TRUNC ( THE_DATE ) THE_DATE,
NAME,
COUNT ( * )
FROM
ORDERS
WHERE
THE_DATE BETWEEN TRUNC ( TO_DATE ( '2013-09-18',
'YYYY-MM-DD' ) )
AND TRUNC ( TO_DATE ( '2013-09-22',
'YYYY-MM-DD' ) )
GROUP BY
TRUNC ( THE_DATE ),
NAME
HAVING
COUNT ( * ) >= 3) A,
ORDERS B
WHERE
A.NAME = B.NAME
AND TRUNC ( A.THE_DATE ) = TRUNC ( B.THE_DATE );
OUTPUT
9/20/2013 12:00:01 AM John
9/20/2013 12:00:02 AM John
9/20/2013 12:00:03 AM John
9/20/2013 12:00:04 AM John