Oracle PLSQL truncate datetime to specific hours - oracle

I have an Oracle PLSQL code generating a list of datetime stamps and I would like to truncate them to the specific hours of 7am and 7pm rather than the beginning of the day.
For example:
01/03/2013 0700 becomes 01/03/2013 0700
01/03/2013 1235 becomes 01/03/2013 0700
01/03/2013 1932 becomes 01/03/2013 1900
02/03/2013 0612 becomes 01/03/2013 1900
My code is currently:
SELECT TRUNC(TRUNC(SYSDATE,'hh') + 1/24 - (ROWNUM) / 24, 'dd') as shift_date
FROM widsys.times
ORDER BY SYSDATE
Thanks

Without conditionals :)
Select your_date,
trunc(your_date - 7/24) + --the date
trunc(to_char(your_date - 7/24,'hh24')/12)/2 + --wich half of day
7/24 --shift the hour
from
your_table;
See a fiddle.

with data(time) as (
select to_date('2013-09-19 00:00:00', 'YYYY-MM-DD HH24:MI:SS') from dual union all
select to_date('2013-09-19 06:45:44', 'YYYY-MM-DD HH24:MI:SS') from dual union all
select to_date('2013-09-19 08:12:25', 'YYYY-MM-DD HH24:MI:SS') from dual union all
select to_date('2013-09-19 18:59:59', 'YYYY-MM-DD HH24:MI:SS') from dual union all
select to_date('2013-09-19 19:00:00', 'YYYY-MM-DD HH24:MI:SS') from dual union all
select to_date('2013-09-19 20:15:35', 'YYYY-MM-DD HH24:MI:SS') from dual union all
select to_date('2013-09-19 23:59:59', 'YYYY-MM-DD HH24:MI:SS') from dual
)
select d.time,
case
when to_number(to_char(d.time, 'HH24')) >= 19 then
trunc(d.time) + 19/24
when to_number(to_char(d.time, 'HH24')) >= 7 then
trunc(d.time) + 7/24
else
trunc(d.time - 1) + 19/24
end as shift_date
from data d
;

Are you looking for a query like this:
SELECT CASE
WHEN TO_CHAR(your_date, 'hh24') > 12
THEN TRUNC(your_date)+ 19/24
ELSE TRUNC(your_date)+ 7/24
END
FROM your_table;

Related

calculate the running total over the column contain date difference in HH:MI:SS format in oracle

I have to find the running total over the column interval.
SELECT
( ( EXTRACT(DAY FROM intrvl) * 24 ) + ( EXTRACT(HOUR FROM intrvl) ) ) ||':'||
EXTRACT(MINUTE FROM intrvl) ||':'||
EXTRACT(SECOND FROM intrvl) ||':'|| as interval
FROM
(
SELECT
( to_timestamp(TO_CHAR(date_column_name,'dd-mon-rrrr hh:mi:ss') ) ) - ( to_timestamp(TO_CHAR(date_column_name,'dd-mon-rrrr hh:mi:ss') ) ) intrvl
FROM
dual
);
currrently Interval column of table has below data:
Interval(HH:mi:ss)
0:4:23
696:1:36
696:4:51
8760:1:18
The best I can come up with is this. Note that the interval data type does not take a format model for displaying - you can't force an interval of 25 hours to be displayed as 25:00:00 (although you can use that to INPUT an interval). Instead, it will be shown as 01 01:00:00 (meaning, a day and an hour).
with
tbl (interv) as (
select interval '0:4:23' hour(9) to second from dual union all
select interval '696:1:36' hour(9) to second from dual union all
select interval '696:4:51' hour(9) to second from dual union all
select interval '8760:1:18' hour(9) to second from dual
)
select interval '1' day * sum(date '2000-01-01' + interv - date'2000-01-01')
as sum_interv
from tbl;
SUM_INTERV
--------------------
+423 00:12:08.000000
In your original attempt you were trying to get a STRING output. I am not sure that's wise, but if that's what you need you can do it like so:
with
tbl (interv) as (
select interval '0:4:23' hour(9) to second from dual union all
select interval '696:1:36' hour(9) to second from dual union all
select interval '696:4:51' hour(9) to second from dual union all
select interval '8760:1:18' hour(9) to second from dual
)
, prep (sum_interv) as (
select interval '1' day * sum(date '2000-01-01' + interv - date'2000-01-01')
from tbl
)
select to_char( extract(day from sum_interv) * 24
+ extract(hour from sum_interv), 'fm999999999' ) || ':' ||
to_char( extract(minute from sum_interv), 'fm00' ) || ':' ||
to_char( extract(second from sum_interv), 'fm00' ) as sum_interv
from prep
;
SUM_INTERV
------------------
10152:12:08

Want to round the data

My Query is :
SELECT TO_CHAR((to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS')+ (level-1)),'DD-MM-YYYY'),
TO_CHAR(to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS') + level,'DD-MM-YYYY') ,
to_number(regexp_substr('7000 T', '^\d+'))/(TO_DATE('04-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS') - TO_DATE('01-01-2018 00:00', 'DD-MM-YYYY HH24:MI:SS'))
|| regexp_substr('7000 T', '[A-Z]') AS IP_PLAN
FROM dual
CONNECT BY level <= to_date('04-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS')-to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS');
I want IP_PLAN like: 2333 T
ROUND(('7000 T'), '[A-Z]') is trying to round a string value, i.e. the T that is extracted from that source string, which doesn't make sense.
You need to round the number you generated just before that:
select to_char(to_date('01-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS') + level - 1,
'DD-MM-YYYY'),
to_char(to_date('01-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS') + level,
'DD-MM-YYYY') ,
round(
to_number(regexp_substr('7000 T', '^[[:digit:]]+'))
/ (to_date('04-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS')
- to_date('01-01-2018 00:00', 'DD-MM-YYYY HH24:MI:SS'))
)
|| regexp_substr('7000 T', '[^[:digit:]]*$') as ip_plan_consumption
from dual
connect by level <= to_date('04-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS')
- to_date('01-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS');
TO_CHAR(TO TO_CHAR(TO IP_PLAN_CONSUMPTION
---------- ---------- ------------------------------------------
01-01-2018 02-01-2018 2333 T
02-01-2018 03-01-2018 2333 T
03-01-2018 04-01-2018 2333 T
so you're doing
round(<number extracted by regex> / <difference in days >)
which is
round(7000 / 3) => round(2333.333...) => 2333
and then appending the T after wards.
I've changed the regex patterns slightly so it picks up the space ans any characters at the end. That's making some assumptions about possible values in that string though - i.e. that it's always one number followed by one non-numeric section.
Incidentally, if you're using fixed dates then it's simpler to use date literals:
select to_char(date '2018-01-01' + level - 1, 'DD-MM-YYYY'),
to_char(date '2018-01-01' + level, 'DD-MM-YYYY') ,
round(
to_number(regexp_substr('7000 T', '^[[:digit:]]+'))
/ (date '2018-01-04' - date '2018-01-01')
)
|| regexp_substr('7000 T', '[^[:digit:]]*$') as ip_plan_consumption
from dual
connect by level <= date '2018-01-04' - date '2018-01-01';
though I imagine the 7000 T and the date values are all being passed in as string in your real code so they need to be converted. You could use a CTE to only convert them once though, instead of repeatedly as you loop round.
SELECT TO_CHAR((to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS')+ (level-1)),'DD-MM-YYYY'),
TO_CHAR(to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS') + level,'DD-MM-YYYY') ,
round(to_number(regexp_substr('7000 T', '^\d+'))/(TO_DATE('04-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS') - TO_DATE('01-01-2018 00:00', 'DD-MM-YYYY HH24:MI:SS')),0)
AS IP_PLAN_CONSUMPTION
FROM dual
CONNECT BY level <= to_date('04-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS')-to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS');
you have to use T in some other column;

Oracle shifts in work with dates

Can you help me with shifts? I need to assign each event what shift it is.
I want to count how many items machine done in every shift. "ILE" means "HOW MANY ITEMS IN SHIFT WERE DONE"
SELECT lz.EVENT,
TO_CHAR(lz.DATA_ZATW, 'YYYY-MM-DD') AS DATA,
CASE WHEN TO_CHAR(lz.DATA_ZATW, 'HH24:MI') BETWEEN '06:00' AND '13:59' THEN 'First Shift'
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24:MI') BETWEEN '14:00' AND '21:59' THEN 'Second Shift'
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24:MI') BETWEEN '22:00' AND '23:59' THEN 'Third Shift'
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24:MI') BETWEEN '00:00' AND '05:59' THEN 'Third Shift'
END AS SHIFT
FROM PLC.LIST lz;
But when I check now query and I have third shift of 2017-08-03 and it is wrong because according to sysdate I shound have first shift only.
Any idea?
EDIT:
Whole query
SELECT "DATA",
"ZMIANA",
"SOV_GAO_1_ILE",
"SOV_GAD_2_ILE",
"SOV_GAM_3_ILE"
FROM (SELECT TO_CHAR(lz.DATA_ZATW, 'YYYY-MM-DD') AS DATA,
CASE WHEN TO_CHAR(lz.DATA_ZATW, 'HH24:MI:SS') BETWEEN '06:00:00' AND '13:59:59.999999' THEN 1
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24:MI:SS') BETWEEN '14:00:00' AND '21:59:59.999999' THEN 2
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24:MI:SS') BETWEEN '22:00:00' AND '23:59:59.999999' THEN 3
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24:MI:SS') BETWEEN '00:00:00' AND '05:59:59.999999' THEN 3
END AS ZMIANA,
lz.LINIA,
lz.DETAL
FROM PLC.LISTA_ZDARZEN lz
GROUP BY lz.DATA_ZATW,
lz.LINIA,
lz.DETAL) PIVOT (COUNT(DETAL) AS ILE FOR LINIA IN ('SOV_GAO_1' SOV_GAO_1, 'SOV_GAD_2' SOV_GAD_2, 'SOV_GAM_3' SOV_GAM_3));
EDIT:
SHIFTS
6-14 01.08 first shift
14-22 01.08 second shift
22-00 01.08 third shift
00-6 02.08 third shift
6-14 02.08 first shift
14-22 02.08 second shift
22-00 02.08 third shift
00-6 03.08 third shift
6-14 03.08 first shift
14-22 03.08 second shift
22-00 03.08 third shift
00-6 04.08 third shift
HERE ARE DATES:
SELECT TO_DATE('2017-08-01 23:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 01.08 Third shift
SELECT TO_DATE('2017-08-01 23:57:58', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 01.08 Third shift
SELECT TO_DATE('2017-08-02 03:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 01.08 Third shift
SELECT TO_DATE('2017-08-02 04:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 01.08 Third shift
SELECT TO_DATE('2017-08-02 06:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 First shift
SELECT TO_DATE('2017-08-02 07:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 First shift
SELECT TO_DATE('2017-08-02 10:24:34', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 First shift
SELECT TO_DATE('2017-08-02 14:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Second shift
SELECT TO_DATE('2017-08-02 15:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Second shift
SELECT TO_DATE('2017-08-02 19:21:10', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Second shift
SELECT TO_DATE('2017-08-02 22:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Third shift
SELECT TO_DATE('2017-08-02 23:55:20', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Third shift
SELECT TO_DATE('2017-08-02 23:55:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Third shift
SELECT TO_DATE('2017-08-03 00:02:34', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Third shift
SELECT TO_DATE('2017-08-03 00:05:34', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Third shift
SELECT TO_DATE('2017-08-03 00:10:38', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 02.08 Third shift
SELECT TO_DATE('2017-08-03 09:01:24', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 03.08 First shift
SELECT TO_DATE('2017-08-03 09:01:32', 'yyyy-mm-dd hh24:mi:ss') FROM DUAL UNION ALL -- 03.08 First shift
SELECT TO_DATE('2017-08-03 17:01:10', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 03.08 Second shift
SELECT TO_DATE('2017-08-03 19:28:45', 'yyyy-mm-dd hh24:mi:ss') FROM DUAL UNION ALL -- 03.08 Second shift
SELECT TO_DATE('2017-08-03 23:54:56', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 03.08 Third shift
SELECT TO_DATE('2017-08-03 23:55:20', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL -- 03.08 Third shift
SELECT TO_DATE('2017-08-03 23:55:56', 'yyyy-mm-dd hh24:mi:ss') FROM DUAL -- 03.08 Third shift
Maybe try this:
CASE WHEN TO_CHAR(lz.DATA_ZATW, 'HH24MI') BETWEEN 600 AND 1359 THEN 'First Shift'
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24MI') BETWEEN 1400 AND 2159 THEN 'Second Shift'
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24MI') BETWEEN 2200 AND 2359 THEN 'Third Shift'
WHEN TO_CHAR(lz.DATA_ZATW, 'HH24MI') BETWEEN 0 AND 559 THEN 'Third Shift'
END AS SHIFT
or like this:
CASE WHEN (lz.DATA_ZATW - TRUNC(lz.DATA_ZATW)) * INTERVAL '1' DAY BETWEEN INTERVAL '6' HOUR AND INTERVAL '13:59:59.999999' HOUR TO SECOND THEN 'First Shift'
CASE WHEN (lz.DATA_ZATW - TRUNC(lz.DATA_ZATW)) * INTERVAL '1' DAY BETWEEN INTERVAL '14' HOUR AND INTERVAL '21:59:59.999999' HOUR TO SECOND THEN 'Second Shift'
...
According to your sample data it works:
WITH t (DATA_ZATW) AS (
SELECT TO_DATE('2017-08-03 09:03:31', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:03:11', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:03:07', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:02:44', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:02:22', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:02:21', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:01:58', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:01:32', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:01:24', 'yyyy-mm-dd hh24:mi:ss') FROM dual)
SELECT DATA_ZATW,
CASE
WHEN TO_CHAR(DATA_ZATW, 'HH24MI') BETWEEN 600 AND 1359 THEN 'First Shift'
WHEN TO_CHAR(DATA_ZATW, 'HH24MI') BETWEEN 1400 AND 2159 THEN 'Second Shift'
WHEN TO_CHAR(DATA_ZATW, 'HH24MI') BETWEEN 2200 AND 2359 THEN 'Third Shift'
WHEN TO_CHAR(DATA_ZATW, 'HH24MI') BETWEEN 0 AND 559 THEN 'Third Shift'
END AS SHIFT
FROM t;
DATA_ZATW SHIFT
03.08.2017 09:03:31 First Shift
03.08.2017 09:03:11 First Shift
03.08.2017 09:03:07 First Shift
03.08.2017 09:02:44 First Shift
03.08.2017 09:02:22 First Shift
03.08.2017 09:02:21 First Shift
03.08.2017 09:01:58 First Shift
03.08.2017 09:01:32 First Shift
03.08.2017 09:01:24 First Shift
I assume at the end you are looking for something like this:
WITH t (DATA_ZATW) AS (
SELECT TO_DATE('2017-08-03 09:03:31', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:03:11', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:03:07', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:02:44', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:02:22', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:02:21', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:01:58', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:01:32', 'yyyy-mm-dd hh24:mi:ss') FROM dual UNION ALL
SELECT TO_DATE('2017-08-03 09:01:24', 'yyyy-mm-dd hh24:mi:ss') FROM dual)
SELECT TRUNC(DATA_ZATW), SHIFT, COUNT(*)
FROM
(
SELECT DATA_ZATW,
CASE
WHEN TO_CHAR(DATA_ZATW, 'HH24MI') BETWEEN 600 AND 1359 THEN 'First Shift'
WHEN TO_CHAR(DATA_ZATW, 'HH24MI') BETWEEN 1400 AND 2159 THEN 'Second Shift'
WHEN TO_CHAR(DATA_ZATW, 'HH24MI') BETWEEN 2200 AND 2359 THEN 'Third Shift'
WHEN TO_CHAR(DATA_ZATW, 'HH24MI') BETWEEN 0 AND 559 THEN 'Third Shift'
END AS SHIFT
FROM t
)
GROUP BY TRUNC(DATA_ZATW), SHIFT;
I think that the only thing You have to do is to substract six hours from data_zatw to assign it to previous day.
select data_zatw, trunc(data_zatw - interval '6' hour) shift_date,
case when to_char(data_zatw, 'HH24') >= '06'
and to_char(data_zatw, 'HH24') < '14' then 1
when to_char(data_zatw, 'HH24') >= '14'
and to_char(data_zatw, 'HH24') < '22' then 2
when to_char(data_zatw, 'HH24') >= '22'
or to_char(data_zatw, 'HH24') < '06' then 3
end shift
from lz
Then make your pivot and aggregations and pivot.
Test data:
with lz as (
select to_date(column_value, 'yyyy-mm-dd hh24:mi:ss') data_zatw
from table(
sys.odcivarchar2list(
'2017-08-01 23:54:56', '2017-08-01 23:57:58', '2017-08-02 03:54:56',
'2017-08-02 04:54:56', '2017-08-02 06:54:56', '2017-08-02 07:54:56',
'2017-08-02 10:24:34', '2017-08-02 14:54:56', '2017-08-02 15:54:56',
'2017-08-02 19:21:10', '2017-08-02 22:54:56', '2017-08-02 23:55:20',
'2017-08-02 23:55:56', '2017-08-03 00:02:34', '2017-08-03 00:05:34',
'2017-08-03 00:10:38', '2017-08-03 09:01:24', '2017-08-03 09:01:32',
'2017-08-03 17:01:10', '2017-08-03 19:28:45', '2017-08-03 23:54:56',
'2017-08-03 23:55:20', '2017-08-03 23:55:56')))
select data_zatw, trunc(data_zatw - interval '6' hour) shift_date,
case when to_char(data_zatw, 'HH24') >= '06'
and to_char(data_zatw, 'HH24') < '14' then 1
when to_char(data_zatw, 'HH24') >= '14'
and to_char(data_zatw, 'HH24') < '22' then 2
when to_char(data_zatw, 'HH24') >= '22'
or to_char(data_zatw, 'HH24') < '06' then 3
end shift
from lz

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.)

Oracle - How to check my date field value has time portion or not

I have a table containing a date type field and it holds few records with date value with time portion and few records only have date value without time portion. How to check which record has time portion and what not without navigating record by record?
This is what I'm using at the moment, but I want something faster:
SELECT MY_TAB.SEQ, MY_TAB.CRTE_DT,
CASE WHEN TRUNC (MY_TAB.CRTE_DT) = MY_TAB.CRTE_DT
THEN 'False' ELSE 'True' END AS "Has Time Portion"
FROM (SELECT 1 AS SEQ,
TO_DATE ('7/28/2013', 'MM/DD/YYYY') AS CRTE_DT
FROM DUAL
UNION
SELECT 2 AS SEQ,
TO_DATE ('11/07/2013 12:27:54', 'MM/DD/YYYY HH24:MI:SS') AS CRTE_DT
FROM DUAL) MY_TAB;
Nice Solution. Just one catch. If the timestamp is of 12:00 am midnight, then the result will be false.
TO_DATE ('11/07/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS') will yield to false
CREATE TABLE MY_TAB
AS
SELECT SEQ, CRTE_DT
FROM (SELECT 1 AS SEQ, TO_DATE ('7/28/2013', 'MM/DD/YYYY') AS CRTE_DT FROM DUAL
UNION
SELECT 2 AS SEQ,
TO_DATE ('11/07/2013 12:27:54', 'MM/DD/YYYY HH24:MI:SS') AS CRTE_DT FROM DUAL
UNION
SELECT 3 AS SEQ,
TO_DATE ('09/5/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS') AS CRTE_DT FROM DUAL
UNION
SELECT 4 AS SEQ, TO_DATE ('4/15/2013 00:00:01', 'MM/DD/YYYY HH24:MI:SS') AS CRTE_DT FROM DUAL
UNION
SELECT 5 AS SEQ, TO_DATE ('12/12/2012 1:01:01', 'MM/DD/YYYY HH24:MI:SS') AS CRTE_DT FROM DUAL);
SELECT MY_TAB.SEQ, MY_TAB.CRTE_DT,
CASE WHEN TRUNC (MY_TAB.CRTE_DT) = MY_TAB.CRTE_DT
THEN 'False' ELSE 'True' END AS "Has Time Portion"
FROM MY_TAB;
If you just want to check the data field contains time portion or not, you can do it by altering the session as,
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'dd/mm/yyyy';
Session altered.
SQL> SELECT SYSDATE FROM dual;
SYSDATE
----------
08/11/2013
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'dd/mm/yyyy hh24:mi:ss';
Session altered.
SQL> SELECT SYSDATE FROM dual;
SYSDATE
-------------------
08/11/2013 08:30:49

Resources