How to fetch data from oracle database in hourly basis - sql

i have one table in my database say mytable, which contents request coming from other source. There is one column in this table as Time, which stores date and time(e.g. 2010/07/10 01:21:43) when request was received. Now i want to fetch the data from this table on hourly basis for each day. Means i want count of requests database receive in each hours of a day. e.g.for 1 o'clock to 2 o'clock say count is 50 ..like this.. I will run this query at the end of day. So i will get requests received in a day group by each hour.
Can anybody help me in this.
I want query which will take less time to fetch the data as my database size is huge.
Any othre way than OMG Ponies answer.

Use the TO_CHAR function to format the DATETIME column, so you can GROUP BY it for aggregate functions:
SELECT TO_CHAR(t.time, 'YYYY-MM-DD HH24') AS hourly,
COUNT(*) AS numPerHour
FROM YOUR_TABLE t
GROUP BY TO_CHAR(t.time, 'YYYY-MM-DD HH24')

Why don't you create another table that stores the count and the date. Create a database job that will run hourly and put the count and sysdate in the new table. Your code will be just querying the new table.
create table ohtertable_count (no_of_rows number, time_of_count date);
Your database job, that will run hourly will be something like
insert into othertable_count
select count(1), sysdate
from othertable;
And you will query the table othertable_count instead of querying your original table.

SELECT To_char(your_column, 'YYYY-MM-DD HH24') AS hourly,
Count(*) AS numPerHour
FROM your_table
WHERE your_column > '1-DEC-18'
AND your_column < '4-DEC-18'
GROUP BY To_char(your_column, 'YYYY-MM-DD HH24')
ORDER BY hourly;

Related

Oracle, execute select * and select count from huge transactional table to tally count of select * from table

I have a huge oracle transactional table where I extract data at 4 hour intervals. I have a requirement to validate the count of this extracted data using a followup select count(*) from table query. However, both the
select * from table where tend between sysdate-4hours and sysdate
and select count(*) from table where tend between sysdate-4hours and sysdate
queries are required to start at the same time, as if they're running in a race.
The objective is to tally the count, and this table receives sizeable no. of transactions at the minute level.
I am adding the parallel hint for the select * query, it's giving good results, however when I am kicking off both the jobs, the extraction finishes long before even though the count query is running exceptionally longer.
how to proceed?
To me, it looks as if you're bothered by question what time is "right now"? because two queries, ran at different times, have different sense of "right now".
So, how about setting it explicitly? Something like this:
declare
l_now date := sysdate;
begin
-- extract data, e.g.
insert into another_table (col1, ool2, ...)
select col1, col2, ...
from huge_table
where date_column between l_now - interval '4' hour and l_now;
-- you want to know number of rows? Easy-peasy
l_cnt := sql%rowcount;
-- you want to count rows explicitly? OK, if you must
select count(*)
into l_cnt
from huge_table
where date_column between l_now - interval '4' hour and l_now;
end;
Don't use an offset from SYSDATE. Instead, store the last retrieved date_column value on the client side (or, if you prefer, in a control table somewhere) and on the next refresh start with that value, pulling all rows >=
(for dates with 1 second granularity, make sure to use >= and not just > )
This way your queries are consistent and it doesn't matter whether they run at exactly the same time.

Better way to create index to optimize query on date range

I am running a query :
select * from users where user_id > 200 and date >= '2020-01-12' and date <= '2020-12-20'.
I have created indexes on user_id, date separately. The total no of records are over 2 billion(2.5 to be exact). There is partitioning included in the table , partitioned by the date range. But still the query is taking over a minute to execute.
can anyone suggest better way to use multi-column index on id, date.

Azure Stream Analytics query to input single data row into Azure SQL

I can insert IoT sensor data into an Azure SQL database via an Azure Stream Analytics query,
SELECT
*
INTO
myazuredb
FROM
mystreamin
except each time a sensor sample is taken, stream analytics creates roughly about 60 messages that are all the same and inserts them into the database. I would like just 1 row for each sample to be inserted based on the Date TIMESTAMP which are all identical. My first thought was to try GROUP BY but after some reading about Stream Analytics Query Language I tried.
SELECT CollectTop(1) OVER (ORDER BY Date ASC) as Date
INTO
myazuredb
FROM
mystreamin TIMESTAMP BY Time
GROUP BY Date, TumblingWindow(second, 60)
This query doesn't insert anything, not sure I am even on the right track. Any ideas on how to approach the problem would be great. Table: Date, DeviceId, Temperature, Humidity, Moisture, EventProcessedUtcTime, PartitionId, EventEnqueuedUtcTime, IoTHub, EventID
SELECT TopOne() OVER (ORDER BY Date ASC) as Date
INTO
myazuredb
FROM mystreamin TIMESTAMP BY Time
GROUP BY Date, TumblingWindow(second, 60)
TopOne() returns top record based on the ordering.

How to get date of all updates to particular table in oracle?

Is there a way to get all modification dates of a particular table in Oracle?
Query below:
select * from sys.dba_tab_modifications
could include number of inserts and updates however not particular dates of each.
You may be able to use Oracle Flashback Query if you have sufficient privs, and sufficient redo logs exist for the time period in question:
select versions_operation
, versions_starttime
, versions_endtime
, <TableAlias>.*
from <TableName> versions between timestamp systimestamp - numtodsinterval(1,'day')
and systimestamp <TableAlias>

My simple oracle query takes too long to complete

I'm trying to run the following SQL statement that is taking too long to finish in Oracle.
Here is my query:
SELECT timestamp from data
WHERE (timestamp IN
(SELECT MIN (timestamp) FROM data
WHERE (( TIMESTAMP BETWEEN :t1 AND :t2))
If anyone can help with optimising this query I would be very grateful.
All you need to speed your query is an index on timestamp:
create index data_timestamp on data(timestamp);
If you are expecting only one result, you can also do:
SELECT MIN(timestamp)
FROM data
WHERE TIMESTAMP BETWEEN :t1 AND :t2
I'm not sure why you would want to output the timestamp multiple times.