how to use Current Timestamp in SQL query (Oracle) - sql

I would like to run the query to show the data before 30 days and after 30 days, I know i should use CURRENT TIMESTAMP to do this and I'm able to run data before 30 days but not after 30 days. Below is my query and kindly advise this situation. Thanks!
COB.COB_FA > CURRENT TIMESTAMP - 30 days and COB.COB_FA > CURRENT TIMESTAMP + 30 days

I think you simply want or:
COB.COB_FA < CURRENT TIMESTAMP - interval '30' day or
COB.COB_FA > CURRENT TIMESTAMP + '30' day

Try below with current_timestamp (+/-) interval '30' day
COB.COB_FA < current_timestamp - interval '30' day or COB.COB_FA > current_timestamp + interval '30' day

sysdate can do this.
`COB.COB_FA between sysdate - 30 and sysdate + 30

this will work:
create table table_date(dd date);
insert into table_date values(trunc(sysdate));
insert into table_date values(trunc(sysdate)+1);
insert into table_date values(trunc(sysdate)+2);
insert into table_date values(trunc(sysdate)+9);
insert into table_date values(add_months(trunc(sysdate),-5));
//inserting more of them
alter session set nls_date_format = 'dd/MON/yyyy hh24:mi:ss';
SELECT * FROM table_date order by dd;
11/MAY/2018 00:00:00
11/JUL/2018 00:00:00
11/OCT/2018 00:00:00
12/OCT/2018 00:00:00
13/OCT/2018 00:00:00
18/OCT/2018 00:00:00
20/OCT/2018 00:00:00
11/JAN/2019 00:00:00
11/MAR/2019 00:00:00
SELECT * FROM table_date where dd>add_months(current_timestamp,1) or
dd<add_months(current_timestamp,-1);
sample output:
11/JAN/2019 00:00:00
11/MAR/2019 00:00:00
11/JUL/2018 00:00:00
11/MAY/2018 00:00:00

Related

Recover all weeks of a month in Oracle SQL

I would like to build a SQL statement to automatically retrieve information about all the weeks of a month.
For example, for the month of February 2023:
Retrieve the first week (Monday to Sunday): 30/01/2023 - 05/01/2023
...
Retrieve the last week :
27/02/2023 - 05/03/2023.
Thanks in advance!
Use a row-generator to generate a list of weeks for the month:
WITH input (month) AS (
SELECT DATE '2023-02-01' FROM DUAL
),
calendar (week_start) AS (
SELECT TRUNC(TRUNC(month, 'MM'), 'IW') + 7 * (LEVEL - 1)
FROM input
CONNECT BY TRUNC(TRUNC(month, 'MM'), 'IW') + 7 * (LEVEL - 1)
< ADD_MONTHS(TRUNC(month, 'MM'), 1)
)
SELECT week_start,
week_start + INTERVAL '6 23:59:59' DAY TO SECOND AS week_end
FROM calendar
Which outputs:
WEEK_START
WEEK_END
2023-01-30 00:00:00
2023-02-05 23:59:59
2023-02-06 00:00:00
2023-02-12 23:59:59
2023-02-13 00:00:00
2023-02-19 23:59:59
2023-02-20 00:00:00
2023-02-26 23:59:59
2023-02-27 00:00:00
2023-03-05 23:59:59
fiddle

How to check overlap date time with specific time SQL

I using postgresSql and i want check overlap date in specific datetime, not range date time.
Example :
I have booking room two time and it booking every saturday :
StartTime EndTime
2019-08-10 00:00:00 2019-08-20 03:00:00
I only want check datetime every saturday(startTime + 7 days) every week. If I put time look like :
StartTime EndTime
2019-08-17 00:00:00 2019-08-17 03:00:00
it overlaps . If i put time :
StartTime EndTime
2019-08-16 00:00:00 2019-08-16 03:00:00
it not overlaps.
If i using command sql look like :
SELECT (TIMESTAMP '2019-08-10 00:00:00', TIMESTAMP '2019-08-10 03:00:00') OVERLAPS (TIMESTAMP '2019-08-10 01:00:00',TIMESTAMP '2019-08-20 01:00:00')
It check all date in range time: 2019-08-10 -> 2019-08-20 and throw overlaps . I only want check 2019-08-10 an 2019-08-17 and throw overlaps. If date 2019-08-11,2019-08-12,2019-08-13,2019-08-14,2019-08-15,2019-08-16,2019-08-18,2019-08-19,2019-08-20 it not overlaps. How to do that.
It same question it monthly. Please help ?
You may add an additional condition If at least one Saturday falls in the given range
SELECT
(TIMESTAMP '2019-08-10 00:00:00', TIMESTAMP '2019-08-10 03:00:00')
OVERLAPS
(TIMESTAMP '2019-08-10 01:00:00', TIMESTAMP '2019-08-20 01:00:00') AND
EXISTS (
select 1 from generate_series(
TIMESTAMP '2019-08-10 00:00:00',
TIMESTAMP '2019-08-10 03:00:00',
INTERVAL '1 DAY'
) as dt where extract(isodow from dt ) = 6
) --ISO day of the week

Running query against quarter or week of the year

I have this query that works for 1 quarter. However, what if I want to do the same query but for 2nd, 3rd, and 4th quarter of the calendar year or even WEEKLY?
How can I do the same query without having to manually change the values defining the quarter or week of the year?
SELECT count(1), AVG(resolved_at::TIMESTAMP - created_at::TIMESTAMP)
FROM supp_cases
WHERE created_at::TIMESTAMP >= '2017-01-01 00:00:00'::TIMESTAMP
AND resolved_at::TIMESTAMP <= '2017-03-31 23:59:59'::TIMESTAMP;
Q1 = 2017-01-01 00:00:00 TO 2017-03-31 23:59:59
Q2 = 2017-04-01 00:00:00 TO 2017-06-30 23:59:59
Q3 = 2017-07-01 00:00:00 TO 2017-09-30 23:59:59
Q4 = 2017-10-01 00:00:00 TO 2017-12-31 23:59:59
How about this?
SELECT TO_CHAR(created_at, 'YYYY-Q') as created_at_yyyyq,
TO_CHAR(resolved_at, 'YYYY-Q') as resolved_at_yyyyq,
count(*)
FROM supp_cases
GROUP BY created_at_yyyyq, resolved_at_yyyyq
ORDER BY created_at_yyyyq, resolved_at_yyyyq;
If you really want rows created and resolved in the same quarter, you can add:
WHERE TO_CHAR(created_at, 'YYYY-Q') = TO_CHAR(resolved_at, 'YYYY-Q')
You might try using intervals, e.g.:
SELECT * FROM example WHERE created_at > '2017-01-01'
AND resolved_at < (DATE('2017-01-01') + INTERVAL '1 WEEKS');
SELECT * FROM example WHERE created_at > '2017-01-01'
AND resolved_at < (DATE('2017-01-01') + INTERVAL '2 MONTHS');

How to create day start and end date in PL SQL

What I am trying to do is to create two timestamps a StartDate timestamp which will be 09/08/2015 00:00:00 and an EndDate time stamp which should be 09/08/2015 23:59:59 as easy as it is to achieve in MS SQL, I have not been able to find a Make_Date function or Add_Days function to get either of the timestamps in Oracle PL SQL.
Can anyone help me out?
Rather than using fractional numbers 86399 / 86400 (which requires some working out when reviewing the code to see why you picked those magic numbers) to get the end date you can explicitly state the time periods using INTERVALS (which is easy to see at a glance what you are doing):
SQL Fiddle
Oracle 11g R2 Schema Setup:
Query 1:
SELECT TRUNC( CURRENT_DATE ) AS START_DATE,
TRUNC( CURRENT_DATE ) + INTERVAL '1' DAY - INTERVAL '1' SECOND AS END_DATE
FROM DUAL
Results:
| START_DATE | END_DATE |
|-----------------------------|-----------------------------|
| September, 08 2015 00:00:00 | September, 08 2015 23:59:59 |
Use TO_DATE to convert string into DATE.
SQL> alter session set nls_date_format='mm/dd/yyyy hh24:mi:ss';
Session altered.
SQL> SELECT to_date('09/08/2015 00:00:00' ,'mm/dd/yyyy hh24:mi:ss') start_date,
2 to_date('09/08/2015 23:59:59' ,'mm/dd/yyyy hh24:mi:ss') end_date
3 FROM dual;
START_DATE END_DATE
------------------- -------------------
09/08/2015 00:00:00 09/08/2015 23:59:59
SQL>
You could also use the ANSI TIMESTAMP Literal.
SQL> SELECT TIMESTAMP '2015-08-09 00:00:00' start_date,
2 TIMESTAMP '2015-08-09 23:59:59' end_date
3 FROM dual;
START_DATE END_DATE
---------------------------- -------------------------------
09-AUG-15 12.00.00.000000000 09-AUG-15 11.59.59.000000000 PM
SQL>
Update OP wants the date literal to be dynamic.
SQL> SELECT TRUNC(SYSDATE) start_date,
2 TRUNC(SYSDATE) + 86399 / 86400 end_date
3 FROM dual;
START_DATE END_DATE
------------------- -------------------
09/08/2015 00:00:00 09/08/2015 23:59:59
Update 2 OP wants to know why the time part is hidden in the date.
SQL> alter session set nls_date_format='mm/dd/yyyy';
Session altered.
SQL> SELECT sysdate FROM DUAL;
SYSDATE
----------
09/08/2015
SQL> alter session set nls_date_format='mm/dd/yyyy hh24:mi:ss';
Session altered.
SQL> SELECT sysdate FROM DUAL;
SYSDATE
-------------------
09/08/2015 15:46:14
So, what happened above? The same SYSDATE returns two different values. The reason is that the DATE has both datetime elements, what you see depends on the display properties driven by your locale-specific NLS settings.
Use TO_CHAR to convert the date into string to display it in your
desired format.
Using values from table:
SELECT
DATE_VALUE,
TRUNC(DATE_VALUE) START_DATE,
TRUNC(DATE_VALUE) + 86399 / 86400 END_DATE
FROM
(SELECT SYSDATE - LEVEL + 1 DATE_VALUE FROM DUAL CONNECT BY LEVEL <= 10)

PostgreSQL time range duration over time series with default end if null

I need to be able to calculate the duration (in seconds) between two time stamps as an aggregate over a time series using a default end_datetime if it is null.
Imagine you have something like a punch card when you puch in and out:
username, start_datetime, end_datetime
What I want is a generated time series of the last N minutes with the duration for all users that overlap within that time frame. So it would be the SUM(end_datetime - start_datetime) where you would COALESCE a default end_datetime if it is null.
So the basic pieces I think I need are:
Generate the time interval:
select TIMESTAMP '2013-01-01 12:01:00' - (interval '1' minute * generate_series(0,5)) as timestamps;
COALESCE a default end_datetime
COALESCE(end_datetime, NOW())
Figure out the seconds difference between the start and end dates
So if one user logged in at 11:56:50 and it is now 12:01:40 we should get a table like:
timestamps duration
-------------------------------------
2013-01-01 12:01:00 40
2013-01-01 12:00:00 60
2013-01-01 11:59:00 60
2013-01-01 11:58:00 60
2013-01-01 11:57:00 60
2013-01-01 11:56:00 10
with t as (select '2013-01-01 11:56:50'::timestamp startt, '2013-01-01 12:01:40'::timestamp endt)
select
timestamps,
extract(epoch from
case
when timestamps=date_trunc('minute',startt) then date_trunc('minute',startt) + interval '1 minute' - startt
when timestamps =date_trunc('minute',endt) then endt- date_trunc('minute',endt)
else interval '60 seconds' end) as durations
from
(select generate_series(date_trunc('minute',startt),date_trunc('minute',endt),'1 minute') timestamps, * from t) a
order by
timestamps desc;
2013-01-01 12:01:00;40
2013-01-01 12:00:00;60
2013-01-01 11:59:00;60
2013-01-01 11:58:00;60
2013-01-01 11:57:00;60
2013-01-01 11:56:00;10
If you have multiple rows with start and end timestamp than the following will work:
select
id,
timestamps,
extract(epoch from
case
when timestamps=date_trunc('minute',startt) then date_trunc('minute',startt) + interval '1 minute' - startt
when timestamps =date_trunc('minute',endt) then endt- date_trunc('minute',endt)
else interval '60 seconds' end) as durations
from
(
select
id,
generate_series(date_trunc('minute',startt) ,
coalesce(date_trunc('minute',endt),date_trunc('minute',Now())),'1 minute') as timestamps,
startt, endt
from test
) a
order by
id, timestamps desc
SQLFiddle