How to get data from a table between date and time range - oracle11g

I have a table call PAYMENT_DET with the fields PAYMENT_DATE DATE, PAYMENT_TIME VARCHAR2 and its data is as shown below where date format is MM/DD/YYYY
PAYMENT_DATE PAYMENT_TIME
2/13/2017 13:03:59
2/13/2017 14:03:59
2/14/2017 01:03:59
2/14/2017 04:03:00
My requirement is, I have two input dates like from date with time and To Date with time. Between the given inputs range i want get details from the above table.
Please suggest me query for this.

A very simple example to help you out. Hope this helps.
SELECT *
FROM
(SELECT 1 col1, '02/13/2017' col2, '13:03:59' col3 FROM dual
UNION
SELECT 2 col1, '02/13/2017' col2, '14:03:59' col3 FROM dual
UNION
SELECT 3 col1, '02/14/2017' col2, '01:03:59' col3 FROM dual
)a
WHERE to_date(a.col2
||' '
||col3,'mM/dd/yyyy hh24:mi:ss') BETWEEN TO_DATE('01/01/2017 00:00:00','mm/dd/yyyy hh24:mi:ss') AND TO_DATE('01/01/2018 00:00:00','mm/dd/yyyy hh24:mi:ss');

Related

plsql count by date and sum up to the date

I'd like to have a plsql request that count the number of row by date and the sum of row up to the date.
The source will be somethings like this (hundreds of dates):
2019.05.01
2019.05.01
2019.05.02
2019.05.03
2019.05.03
2019.05.03
...
and the result:
date nb sum
-------------------
2019.05.01 2 2
2019.05.02 1 3
2019.05.03 3 6
. . .
The key here is to use an Aggregate Function as an Analytical function which is what the SUM(COUNT(dt)) OVER (ORDER BY dt) in the query below is doing.
WITH dates AS
(
SELECT to_date('2019.05.01', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.01', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.02', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.03', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.03', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.03', 'YYYY.MM.DD') AS dt FROM dual
)
SELECT dt, COUNT(dt) AS nb, SUM(COUNT(dt)) OVER (ORDER BY dt) AS sum
FROM dates
GROUP BY dt
;
First half is relatively easy. Something like
SELECT date, count(*) from table GROUP BY date ORDER BY date;
But I'm not sure about the cumulative sum. If it's a manual process then I'd probably just import into Excel and do it there to be honest.

Eliminate ID if Col2 = (1,2,3)

I am using teradata sql, and I have the following input
If col2 has (1,2,3) values then delete the Id from table, so my desired table is:
I tried all possible ways, but cannot get to eliminate the IDs? Any help or suggestion will help. thanks
DELETE FROM yourTable
WHERE Id IN ( SELECT Id FROM yourTable WHERE col2 IN (1,2,3) )
If you actually want to delete those IDs you better use #MudassirHasan's solution, but if you want to select the other IDs you can utilize Conditional Aggregation in a Group Max:
select *
from mytable
qualify
max(case when col2 (1,2,3) then 1 else 0 end) -- will return zero when those values don't exist
over (partition by id) = 0 -- for an ID

Oracle Timestamp based calculation on every day using Two datetime column

I have a table that contains two time stamp t1(event open date) and t2(event close date) and a primary key eventid.
If event is open then t2 will be null whenever even gets closed the same row will be get updated with event closure date t2.
For example I want to check how many issues are open on every day bases on opened date (t1) from 01-apr-2016 to 10-apr-2016.
I have to calculate how many events are open for every day based on a selected date range.
Lets say if eventid 1 has got opened on 1st-APR and got closed on 10th-APR and I am calculating the number of opened issues for every day on 11th-APR then it should give me number of open event 1 from 1st-APR to 10th-APR.
Table Structure:-
================================================
EVENTID T1 T2
================================================
1 01-apr-2016 10-apr-2016
2 02-apr-2016 08-apr-2016
3 05-apr-2016 09-apr-2016
Expected Output:-
==============================================================================
DATE TOTAL_OPEN_EVENTS
==============================================================================
01-apr-2016 1
02-apr-2016 2(1 issue open on 1st(not closed on 2nd) and 1 on 2nd)
03-apr-2016 2
04-apr-2016 2
05-apr-2016 3
06-apr-2016 3
07-apr-2016 3
08-apr-2016 2(1 issue got closed on 8th(which was opened on 2nd))
09-apr-2016 2
10-apr-2016 0
How to do this kind of calculation in Oracle database ?
In order to generate the end report, you need a row for each date in your desired range. You could either use a calendar table, if available, or I find using a query on DUAL using CONNECT BY LEVEL < some_number works well to generate rows on the fly. (In this case "some_number" will be the number of days you want to report on.)
From there, you just need to join the individual dates to the date ranges in your event table:
-- create table "events" table
create table event_date_ranges
as
select 1 as event_id, TO_DATE('2016-APR-01', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-10', 'YYYY-MON-DD') as end_date from dual
union all
select 2 as event_id, TO_DATE('2016-APR-02', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-08', 'YYYY-MON-DD') as end_date from dual
union all
select 3 as event_id, TO_DATE('2016-APR-05', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-09', 'YYYY-MON-DD') as end_date from dual
;
with
date_range_qry as
(-- one way to set the start and end dates for your report
select TO_DATE('2016-APR-01', 'YYYY-MM-DD') as report_start_date
, TO_DATE('2016-APR-10', 'YYYY-MM-DD') as report_end_date
from dual
)
, dates_qry
as
(
-- generate a row for all dates between 2016-APR-01 and 2016-APR-10
select report_start_date + ROWNUM - 1 as report_date
from dual
cross join
date_range_qry drq
connect by level <= (drq.report_end_date - drq.report_start_date + 1)
)
select dq.report_date, count(edr.event_id) as total_open_events
from dates_qry dq
left outer join
event_date_ranges edr
on dq.report_date >= edr.start_date
and dq.report_date < edr.end_date
group by dq.report_date
order by dq.report_date
Output:
REPORT_DATE TOTAL_OPEN_EVENTS
2016-APR-01 1
2016-APR-02 2
2016-APR-03 2
2016-APR-04 2
2016-APR-05 3
2016-APR-06 3
2016-APR-07 3
2016-APR-08 2
2016-APR-09 1
2016-APR-10 0
You can try this:
create table events_log
as
select 1 as event_id, TO_DATE('01-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('10-04-2016', 'DD/MM/YYYY') as T2 from dual
union all
select 2 as event_id, TO_DATE('02-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('08-04-2016', 'DD/MM/YYYY') as T2 from dual
union all
select 3 as event_id, TO_DATE('05-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('09-04-2016', 'DD/MM/YYYY') as T2 from dual
;
--------------
select v.REPORT_DATE, count(t.EVENT_ID) as open_event
from events_log t,
(select to_date('01/04/2016', 'DD/MM/YYYY') + ROWNUM - 1 as report_date
from dual
connect by level <= (to_date('11/04/2016', 'DD/MM/YYYY') -
to_date('01/04/2016', 'DD/MM/YYYY') + 1)) v
where t.T1(+) <= v.report_date
and t.T2(+) >= v.report_date
group by v.report_date
order by v.report_date;
Output will be:
report_date open_event
01/04/2016 1
02/04/2016 2
03/04/2016 2
04/04/2016 2
05/04/2016 3
06/04/2016 3
07/04/2016 3
08/04/2016 3
09/04/2016 2
10/04/2016 1
11/04/2016 0

Assigning the rownnum values in a column in the table in ORACLE database?

Example:
It does not work.
UPDATE column_name SET rownum FROM table_name
This work!
UPDATE table_name SET column_name = rownum;
This works but the update is performed incorrectly
SELECT * FROM table_name ORDER BY column_name;
UPDATE table_name SET column_name = rownum;
I wish the following update behavior:
Note:'rownum ' It is not a physical column of the table
/*
pc_comentario = tableName
cod_comentario = columnName (Reference column for sorting)
dtc_andamento = columnDay (Reference column to update the "columnName" according to the order of this column)
*/
rownum | columnName | columnDay
1 1 day 1
2 5 day 5
3 7 day 2
After change with update
rownum | columnName (Update this column) | columnDay (sort by this column)
1 1 day 1
2 2 day 2
3 3 day 5
ALMOST DONE! this column 'cod_comentario_1 "which was materialized in RAM is correct. I need this column" cod_comentario_1 "that does not exist in the table is acknowledged in the consultations with java.
SELECT cod_comentario, dtc_andamento, cod_processo ,
ROW_NUMBER()
OVER (PARTITION BY cod_processo
ORDER BY dtc_andamento) cod_comentario_1
FROM pc_comentario
upadate do not work this way:
UPDATE (
SELECT cod_processo
ROW_NUMBER()
OVER (PARTITION BY cod_processo
ORDER BY dtc_andamento)cod_comentario_1
FROM pc_comentario
) SET cod_comentario_1)
order by Seq
I must enter the values of this consultation in a new column that I created
SELECT
ROW_NUMBER()
OVER (PARTITION BY cod_processo
ORDER BY dtc_andamento DESC)
FROM pc_comentario
Try:
UPDATE table_name
SET column_name = rownum
Shouldn't it be like below rather; I believe UPDATE statement has no FROM clause
UPDATE table_name SET column_name = rownum;
Again, it will work only if rownum is an existing column in your table. If you are trying to use Oracle rownum instead then consider using row_number() function rather
update table_name set column_name =
select rn from ( select column_name, row_number() over (order by column_name) rn
from table_name ) xx;
As you state yourself, rownum is a virtual column. It assigns a sequential value to each row of a particular result set. Which means that the row number of a row could be completely different in the result set of a different query.
If you really want to show the row number as part of the result set, specify it as you would any column:
select rownum as columnName, columnDay
from table
order by ...;

Select weekend or weekday data from a table based on date param

How can I select data from a table based on weekday or weekend, like
if date is a weekday then select only historical weekday data from the table &
if date is a weekend then select only historical weekend data.
I have tried to do that in this way but no luck
DECLARE #MyDate DATE = '08/17/2013'
SELECT datename(dw,#MyDate)
SELECT * FROM MyTable
WHERE
datename(dw,DateColumnInTable) IN (
CASE WHEN (datename(dw,#MyDate) IN ('Saturday','Sunday')) THEN '''Saturday'',''Sunday'''
ELSE 'Monday'',''Tuesday'',''Wednesday'',''Thursday'',''Friday'
END )
Any I can see lots of data in my table for saturday and sunday but this query is giving me blank record set.
Here's one way:
DECLARE #MyDate DATE = '08/17/2013'
IF (DATEPART(weekday, #MyDate) IN (1,7))
SELECT *
FROM MyTable
WHERE DATEPART(weekday, DateColumnInTable) IN (1,7)
ELSE
SELECT *
FROM MyTable
WHERE DATEPART(weekday, DateColumnInTable) BETWEEN 2 AND 6
If you would like to do it in one clause you can do something like the following, but it may perform worse:
SELECT *
FROM MyTable
WHERE (DATEPART(weekday, #MyDate) IN (1,7) AND DATEPART(weekday, DateColumnInTable) IN (1,7))
OR (DATEPART(weekday, #MyDate) BETWEEN 2 AND 6 AND DATEPART(weekday, DateColumnInTable) BETWEEN 2 AND 6)

Resources