How to get cout(*) based on sysdate -1 - oracle

I want to get count(*) with table name printed with records which are sysdate-1 in oracle.
Select abc , count(*) from abc where dat_last_mnt < sysdate -1
With regards
Sree

In Oracle, a DATE is a binary data-type with 7 bytes for century, year-of-century, month, day, hour, minute and second and it ALWAYS has those 7 components.
If you want to find a count of the values that were yesterday then you need to filter to find the range of values between 00:00:00 and 23:59:59 on that day and you need to include a GROUP BY clause with all the columns you are not aggregating by:
SELECT column_name,
count(*)
FROM table_name
WHERE dat_last_mnt >= TRUNC(SYSDATE) - INTERVAL '1' DAY
AND dat_last_mnt < TRUNC(SYSDATE)
GROUP BY column_name;
Which, for the sample data:
CREATE TABLE table_name (column_name, dat_last_mnt) AS
SELECT 'A', TRUNC(SYSDATE) - INTERVAL '2' DAY + INTERVAL '20' HOUR FROM DUAL UNION ALL
SELECT 'A', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '0' HOUR FROM DUAL UNION ALL
SELECT 'A', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '4' HOUR FROM DUAL UNION ALL
SELECT 'A', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '8' HOUR FROM DUAL UNION ALL
SELECT 'A', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '12' HOUR FROM DUAL UNION ALL
SELECT 'A', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '16' HOUR FROM DUAL UNION ALL
SELECT 'A', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '20' HOUR FROM DUAL UNION ALL
SELECT 'A', TRUNC(SYSDATE) - INTERVAL '0' DAY + INTERVAL '0' HOUR FROM DUAL UNION ALL
SELECT 'B', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'B', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '2' HOUR FROM DUAL UNION ALL
SELECT 'B', TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '3' HOUR FROM DUAL UNION ALL
SELECT 'B', TRUNC(SYSDATE) - INTERVAL '0' DAY + INTERVAL '0' HOUR FROM DUAL;
Outputs:
COLUMN_NAME
COUNT(*)
A
6
B
3
db<>fiddle here

Related

how to get last businessday of last month in oralce

I have data like this my table
2020-01-01 H
2020-01-02 B
2020-01-03 B
2020-01-04 B
.
2020-01-29 B
2020-01-30 H
2020-01-31 H
2020-01-02 H
2020-02-02 H
2020-02-03 B
2020-02-04 B
2020-02-05 B
.
now my problem is in the current month i need to check third business day i.e in this case 2020-02-05 i need to get last business day of last month. i.e.2020-01-29
By adding 2 columns:
row_number() over(partition by trunc(date_value,'MM'), day_type order by date_value) as rn_month_asc,
row_number() over(partition by trunc(date_value,'MM'), day_type order by date_value desc) as rn_month_desc
in a month the 3rd business day will have rn_month_asc=3 and day_type ='B' and the latest business day will have rn_month_desc=1 and day_type ='B', and easy to query other situations if you need to.
in the current month I need to check third business day
From Oracle 12, you can use:
SELECT date_value
FROM table_name
WHERE TRUNC(SYSDATE, 'MM') <= date_value
AND date_value < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1)
AND day_type = 'B'
ORDER BY date_value ASC
OFFSET 2 ROWS
FETCH NEXT ROW ONLY;
Which, for the sample data:
CREATE TABLE table_name (date_value, day_type) AS
SELECT DATE '2020-01-01', 'H' FROM DUAL UNION ALL
SELECT DATE '2020-01-02', 'B' FROM DUAL UNION ALL
SELECT DATE '2020-01-03', 'B' FROM DUAL UNION ALL
SELECT DATE '2020-01-04', 'B' FROM DUAL UNION ALL
SELECT DATE '2020-01-05', 'B' FROM DUAL UNION ALL
SELECT DATE '2020-01-28', 'B' FROM DUAL UNION ALL
SELECT DATE '2020-01-29', 'B' FROM DUAL UNION ALL
SELECT DATE '2020-01-30', 'H' FROM DUAL UNION ALL
SELECT DATE '2020-01-31', 'H' FROM DUAL UNION ALL
SELECT DATE '2020-01-02', 'H' FROM DUAL UNION ALL
SELECT DATE '2020-02-02', 'H' FROM DUAL UNION ALL
SELECT DATE '2020-02-03', 'B' FROM DUAL UNION ALL
SELECT DATE '2020-02-04', 'B' FROM DUAL UNION ALL
SELECT DATE '2020-02-05', 'B' FROM DUAL;
If the current month was 2020-01 then the output is:
DATE_VALUE
04-JAN-20
I need to get last business day of last month
SELECT date_value
FROM table_name
WHERE ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -1) <= date_value
AND date_value < TRUNC(SYSDATE, 'MM')
AND day_type = 'B'
ORDER BY date_value DESC
FETCH FIRST ROW ONLY;
If the current month is 2020-02 then the output is:
DATE_VALUE
29-JAN-20
fiddle

get data in 'n' hours interval between two dates oracle

i am trying to get data between two dates in an 'n' hour intervals ... the problem is that i am not getting desired result after 8 hour intervals ... my value in 'n' interval can range up to any number between 1 to 120.
Following is the Pseudo code of what i am tying to do:
-- i first select number of hours between two dates
SELECT
24 * (SYSDATE - to_date('2018-04-16 15:20', 'YYYY-MM-DD hh24:mi')) AS diff_hours
FROM dual;
-- Then i use the above value in CONNECT BY ROWNUM <= ROUND((hours between two dates/n),0) to get data in n intervals
SELECT TRUNC(sysdate - (rownum/ROUND((24/n),0)),'HH24') as the_hour
FROM dual
CONNECT BY ROWNUM <= ROUND((hours between two dates/n),0) ;
Sample query
SELECT
24 * (SYSDATE - to_date('2018-04-16 15:20', 'YYYY-MM-DD hh24:mi')) AS diff_hours
FROM dual;
SELECT TRUNC(sysdate - (rownum/ROUND((24/8),0)),'HH24') as the_hour
FROM dual
CONNECT BY ROWNUM <= ROUND((724/8),0) ;
How can i change above query to get data in 'n' hour intervals between two dates, with n being any number of hours?
Remove the first ROUND() in your SELECT
SELECT TRUNC (SYSDATE - (ROWNUM / (24 / 9)), 'HH24') AS the_hour
FROM DUAL
CONNECT BY ROWNUM <= ROUND ( (724 / 9), 0);
try this,
SELECT TO_DATE(:p_date1, 'MM/DD/YYYY') + (FLOOR((rownum*:p_interval)/24) + (MOD((rownum*:p_interval), 24)/24)) dt
FROM DUAL
CONNECT BY (rownum*:p_interval) <= ((TO_DATE(:p_date2, 'MM/DD/YYYY')+.5) - TO_DATE(:p_date1, 'MM/DD/YYYY') + (MOD((rownum*:p_interval), 24)/24)) * 24
ORDER BY 1;

How to query for a specific day of the month in Oracle

Trying to automate a query that will pull data for the current month where the day of the month (in the date field) is >= the 15th. Is this possible? If so, what is the syntax to achieve this?
I want to be able to run this query each month without having to change anything. So in May, it would automatically pull any item where the date was >= 5/15/16. In June, it would pull items where the date was >= 6/15/16. And so on.....
Any help in this would be greatly appreciated. Thanks
This will allow you to use any indexes you have on your date_field column:
SELECT *
FROM table_name
WHERE date_field >= TRUNC( SYSDATE, 'MM' ) + INTERVAL '14' DAY
AND date_field < ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), 1 );
If your date/time fields are of type timestamp you can do
select x from <your_table>
where EXTRACT(DAY from <timestamp field>) >=15
and EXTRACT(MONTH from <timestamp field>) = EXTRACT(MONTH FROM CURRENT_TIMESTAMP)
and EXTRACT(YEAR from <timestamp field>) = EXTRACT(YEAR FROM CURRENT_TIMESTAMP);
I think what you're after is something like:
with sample_data as (select 1 id, to_date('01/06/2016', 'dd/mm/yyyy') dt from dual union all
select 2 id, to_date('10/06/2016', 'dd/mm/yyyy') dt from dual union all
select 3 id, to_date('14/06/2016', 'dd/mm/yyyy') dt from dual union all
select 4 id, to_date('15/06/2016', 'dd/mm/yyyy') dt from dual union all
select 5 id, to_date('16/06/2016', 'dd/mm/yyyy') dt from dual union all
select 6 id, to_date('30/06/2016', 'dd/mm/yyyy') dt from dual union all
select 7 id, to_date('01/07/2016', 'dd/mm/yyyy') dt from dual)
select *
from sample_data
where dt >= trunc(sysdate, 'mm') + 14
and dt < last_day(trunc(sysdate)) + 1;
ID DT
---------- ----------
4 15/06/2016
5 16/06/2016
6 30/06/2016
(If you wanted rows with any date greater than the 15th of the current month, then remove the last predicate in the where clause.)

Count the no of saturdays and sundays in date range - oracle [duplicate]

This question already has answers here:
Number of fridays between two dates
(7 answers)
Closed 8 years ago.
I have two parameters(start_Date,end_Date) from table1
I'm trying to count no of saturdays and sundays in a date range
star_Date=8/20/2014 13:52
end_Date=8/28/2014 13:52
And result should be like this
Start_Date end_date No_of_leaves
8/20/2014 13:52 8/28/2014 13:52 2
Update Section
SELECT retouch_req_time,retouch_submit_time,(
SELECT Count(*) FROM (SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday') dt
FROM (WITH t AS (SELECT To_date (retouch_req_time, 'MM/DD/YYYY HH24:MI') start_date, To_date (retouch_submit_time, 'MM/DD/YYYY HH24:MI') end_date FROM TT))
CONNECT BY LEVEL <= end_date - start_date + 1) WHERE dt IN ('friday','saturday')) as worked_hours
FROM TT
You can try using hierarchical queries
WITH t
AS (SELECT To_date ('8/20/2014 13:52', 'MM/DD/YYYY HH24:MI') start_date,
To_date ('8/28/2014 13:52', 'MM/DD/YYYY HH24:MI') end_date
FROM dual)
SELECT Count(*)
FROM (SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday') dt
FROM t
CONNECT BY LEVEL <= end_date - start_date + 1)
WHERE dt IN ( 'friday', 'saturday' );
RESULT
------
2
* The dates are listed by expanding the range.
* The TO_CHAR function is used to obtain the weekday
* Count everthing which is a friday or saturday
If you want to find the day wise count, then you can try
SELECT To_char(dat, 'DY'),
Count(*)
FROM (SELECT To_date ('8/20/2014 13:52', 'MM/DD/YYYY HH24:MI')
+ num dat
FROM (SELECT LEVEL - 1 num
FROM dual
CONNECT BY LEVEL <= Abs(To_date ('8/20/2014 13:52',
'MM/DD/YYYY HH24:MI') -
To_date (
'8/28/2014 13:52'
,
'MM/DD/YYYY HH24:MI')) - 1
))
WHERE To_char(dat, 'DY') IN ( 'FRI', 'SAT' )
GROUP BY To_char(dat, 'DY');
RESULTS
TO_CHAR(DAT,'DY') COUNT(*)
----------------- --------
FRI 1
SAT 1
You can calculate the number of saturdays and sundays like this:
with t(d) as (
select sysdate + level from dual connect by rownum < 10
)
select count(case when trim(to_char(d, 'DAY')) in ('SATURDAY', 'SUNDAY') then 1 end) cnt from t
CNT
---
2
If you don't have a range of dates then:
with t(a, b) as (
select sysdate a, sysdate + 10 b from dual connect by rownum < 10
), t2(d) as (
select a + level - 1 from t connect by rownum <= b - a
)
select count(case when trim(to_char(d, 'DAY')) in ('SATURDAY', 'SUNDAY') then 1 end) cnt from t2
CNT
---
2

how to picking up the min date only one line in the table by Group by

WITH A AS (
SELECT SYSDATE date_1,'1' data_1 ,1 item FROM DUAL
UNION
SELECT add_months(SYSDATE,7) date_1,'8'data, '1' item_ FROM DUAL
UNION
SELECT add_months(SYSDATE,6)+ 10, '4' data, '1' item FROM dual
UNION
SELECT add_months(SYSDATE,6) date_1,'3' data, '2' item FROM DUAL
)
SELECT min(date_1), data,item
FROM a
WHERE date_1 BETWEEN add_months(SYSDATE,6) AND last_day(add_months(SYSDATE,7))
GROUP BY item,data
the result show that item 1 has two lines, but I only want the min date one, how to change the code to display one data for one item at min(date).
*and i need the date match the right data and item *.
thank you for reading and look forward for right answer.
i find a not good way to invoke what i mean: group by item and select the min date_1 in the scope
WITH A AS (
SELECT SYSDATE date_1, '1' data, '1' item FROM DUAL
UNION SELECT add_months(SYSDATE,7) date_1, '8' data, '1' item FROM DUAL
UNION SELECT add_months(SYSDATE,6)+ 10, '4' data, '1' item FROM dual
UNION SELECT add_months(SYSDATE,6) date_1, '3' data, '2' item FROM DUAL
)
select a.* from A a,(select min(date_1) date_1,item from A
where
date_1 BETWEEN add_months(SYSDATE, 6)
AND last_day(add_months(SYSDATE, 7))
group by item) b where a.date_1 = b.date_1 and a.item= b.item
Use KEEP ... FIRST:
SQL> WITH A AS (
2 SELECT SYSDATE date_1, '1' data, '1' item FROM DUAL
3 UNION SELECT add_months(SYSDATE,7) date_1, '8' data, '1' item FROM DUAL
4 UNION SELECT add_months(SYSDATE,6)+ 10, '4' data, '1' item FROM dual
5 UNION SELECT add_months(SYSDATE,6) date_1, '3' data, '2' item FROM DUAL
6 )
7 SELECT MIN(date_1), item,
8 MAX(data) KEEP (DENSE_RANK FIRST ORDER BY date_1) DATA
9 FROM a
10 WHERE date_1 BETWEEN add_months(SYSDATE, 6)
11 AND last_day(add_months(SYSDATE, 7))
12 GROUP BY item;
MIN(DATE_1) ITEM DATA
----------- ---- ----
01/06/2013 1 4
22/05/2013 2 3
This will select the (MAX) data on the subset of row that has the lowest date (here only one row).

Resources