I am trying to write sql query for the following scenario. It would be great if can get any help on it.
Scenario :
I have a table(emp) which has three columns id,time and value. There is no primary key in the table. time is a date column holding date and timestamp.
Table will be started to update from afternoon onwards. So table will have yesterday data in it from morning to afternoon. Before inserting current data in it all the yesterday's rows will be cleared and table will be start to be updated dynamically from noon till evening .But I need to run the query running from morning onwards and my query should not fetch yesterday's data. So from morning to afternoon I should ideally wait for data to come and should not fetch any rows and start to fetch once the current date data was inserted into it.
I need to run the query for every five minutes and when I run the query I should get all the latest rows in the table so that whenever there is a update in the table those rows will be fetched .
For example when the table is updated from 1 PM onwards. I should get all the rows when i start the first query and after five minutes when i once again run the same query at 1.05 i should get all the rows inserted between 1PM and 1.05PM.
My idea :
Select max(time) from emp;
At the start of the day I should check the max time in the table and it will be definitely yesterday date so I will set today date(2018-07-14 00:00:00) in a local variable or if it's today's date then that value will be stored in the local variable.
I can also do the same in the above query by comparing it with sysdate like below query but not sure about the performance as I saw it took time by comparing with all the rows I guess. See the modified above query below
select max(time) from emp where time = sysdate;
After getting the max time from the table , will have it one variable say lastquerytime, then query the table which has rows greater than this time stamp so that we can fetch all the latest rows for every five minutes.
Select id,time,value from emp where time > lastquerytime;
So the idea is getting all the rows and check the maximum timestamp in it and query the table next time with rows having timestamp greater than this max timestamp. Like this need to do the same for every five minutes till the end of the day.
Now I am using two queries to achieve this scenario.
Any suggestions for better approach and queries to write for this scenario will help me a lot.
You should use something like to get data from yesterday:
SELECT id,time,value FROM emp WHERE time BETWEEN TRUNC(SYSDATE - 1) AND TRUNC(SYSDATE) - 1/86400
If I understand correctly, you want all rows on the maximum date of the table.
If so:
select e.*
from emp
where time >= (select trunc(max(time)) from emp);
If you want the results based on clock-time, then you would use trunc(sysdate) instead.
Related
Hello i have two tables First table is called time and it has rows
Id,time,status,doctor
Second table is called appointments and it has rows
Id,doctorname,doctoremail,patientname,service,comment,time,date,status
The first table shows only time schedules options (08:00 until 16:00) and if status=1 for a specific time (08:00 has status=1) this time option wont show since is already booked.
The appointments saves values from the past, current day and future. I want to make an update query where the second table appointments updates the status of first table time if there are any todays date appointments.
Something like this
update time set status='0' where time=(select time from appointments where date='05/12/2022' and doctoremail='something#gmail.com')
Is it possible to do such a query?
Thank you in advance
As #Jona Metzler helped me the final query that works is
update time set status='0' where doctor='something#gmail.com' and time IN (select time from appointments where date='05/12/2022' and doctoremail='something#gmail.com')
I have a table that will get refreshed every Friday on a weekly basis, I need to place a check to make sure , the records that is available in the table is the latest refreshed records before we consume the data.
What is the best way to check using ORACLE SQL query.
The check query could be as follows
select min(update_date) from your_table
If the result is less that the last expected refresh date, you see that at least some rows were not updated.
I have a cursor which deletes records from a table which are more than or equal to 1 year old. It keeps past one year data and deletes records whose creation_date (column_name) is greater than one year. The cursor is running for the past 3 years. I now have to recover deleted records.
I tried something like this
select * from <table> as of timestamp systimestamp - interval '1' hour;
But it shows data for a particular instance of time in the past. I want all the records which were deleted from the table by the cursor. Can anyone assist with this?
try something like this:
select * from <table> as of systimestamp - interval '1' hour
minus
select * from <table>;
that should show you any records that existed an hour ago but don't exist now. If that shows you what you want, then use that to feed an insert as select statement to recover the missing records.
Below is the problem statement :
I have a table where we are inserting some data along with a business date of that Hospital along with the create time stamp.
The business date (Bday) defines the logical day for which the hospital has done the business and the create time stamp (create_ts) defines the timestamp at which the record was inserted in our database.
The business date could be 1 day ahead of the create timestamp as the create timestamp is in PST and the Hospital can be in South Asia, Australia region.
Also a hospital can be opening for next day if they accidentally closed for today's business date in the application.
I need to sync the record from a staging database to main database.
I want to sync the record with minimum create timestamp first. But order by is a costly operation as sometimes the number of records to be synced are more than 100k
10 Different threads are running to sync the records each with a batch size of 50.
First solution tries was to pickup the records with business date = min business date but there were some complexities:
1) as there were some records with minimum business date which were not syncing due to some issue as a result the next day records were never picked up without manual interventions.
2) There were hospitals which opened for a future business date ( for example today is 13th and they closed accidentally for it so they were opened for business date 14th ). SO these records did not get process as the business date was greater than min business date.
Thought of picking records where the create timestamp is between minimum create timestamp and +1 hour .
But there could be again issue as mentioned in point (1) and there may not be any record to be synced between the stuck record with minimum create timestamp and +1 hour.
Please suggest a solution for the query
Few columns in the table are : Hname (Hospital Name) , Hloc (Hospital location) , Dseq (Per day sequence number ) , Bday (business date ) , create_ts and modify_ts
Oracle doesn't guaranty the order of the resultset if you don't use "ORDER BY" clause.
But you may consider using CDC for Oracle 11g or GoldenGate for Oracle 12c - it should be very efficient. New data will be replicated almost immediately. Oracle will take care of it.
in general: no order by --> no guarantee on the order of result set.
I'm trying to generate monthly records in one table based on instructions in another table. Software - MS Access 2007, though I'm looking for an SQL solution here. To greatly simplify the matter, let's say the following describes the tables:
TaskManager:
- DayDue
- TaskName
Task:
- DateDue
- TaskName
So what happens is that there may be an entry in TaskManager {15, "Accounts due"}, so this should lead to an "Account due" record in the Task table with the due date being the 15th of each month. I'd want it to create records for the last few months and the next year.
What I'm thinking that I need to do is first create a SELECT query that results in x records for each record in the TaskManager table, with a date for each month. After that, I do an INSERT query which inserts records into the Task table if they do not EXIST in the aforementioned SELECT query.
I think I can manage the INSERT query, though I'm having trouble figuring out how to do the SELECT query. Could someone give me a pointer?
You could use a calendar table.
INSERT INTO Task ( DateDue, TaskName )
SELECT calendar.CalDate, TaskManager.TaskName
FROM calendar, TaskManager
WHERE (((Day([CalDate]))=TaskManager.DayDue)
AND ((calendar.CalDate)<#7/1/2013#));
The calendar table would simply contain all dates and other such relevant fields as work day (yesno). Calendar tables are generally quite useful.
Here is the solution I developed using Remou's Calendar table idea.
First create a Calendar table, which simply contains all dates for a desired range. It's easy to just make the dates in Excel and paste them into the table. This is also a very reliable way of doing it, as Excel handles leap years correctly for the modern range of dates.
After building this table, there are three queries to run. The first is a SELECT, which selects every possible task generated by the TaskManager based on the date and frequency. This query is called TaskManagerQryAllOptions, and has the following code:
SELECT TaskManager.ID, Calendar.CalendarDate
FROM TaskManager INNER JOIN Calendar ON
TaskManager.DateDay = Day(Calendar.CalendarDate)
WHERE (TaskManager.Frequency = "Monthly")
OR (TaskManager.Frequency = "Yearly" AND
TaskManager.DateMonth = Month(Calendar.CalendarDate))
OR (TaskManager.Frequency = "Quarterly" AND
(((Month(Calendar.CalendarDate)- TaskManager.DateMonth) Mod 3) = 0));
The bulk of the above is to cover the different options a quarterly Day and Month pair could cover. The next step is another SELECT query, which selects records from the TaskManagerQryAllOptions in which the date is within the required range. This query is called TaskManagerQrySelect.
SELECT TaskManagerQryAllOptions.ID, TaskManager.TaskName,
TaskManagerQryAllOptions.CalendarDate
FROM TaskManagerQryAllOptions INNER JOIN TaskManager
ON TaskManagerQryAllOptions.ID = TaskManager.ID
WHERE (TaskManagerQryAllOptions.CalendarDate > Date()-60)
AND (TaskManagerQryAllOptions.CalendarDate < Date()+370)
AND (TaskManagerQryAllOptions.CalendarDate >= TaskManager.Start)
AND ((TaskManagerQryAllOptions.CalendarDate <= TaskManager.Finish)
OR (TaskManager.Finish Is Null))
ORDER BY TaskManagerQryAllOptions.CalendarDate;
The final query is an INSERT. As we will be using this query frequently, we don't want it to generate duplicates, so we need to filter out already created records.
INSERT INTO Task ( TaskName, TaskDate )
SELECT TaskManagerQrySelect.TaskName, TaskManagerQrySelect.CalendarDate
FROM TaskManagerQrySelect
WHERE Not Exists(
SELECT *
FROM Task
WHERE Task.TaskName = TaskManagerQrySelect.TaskName
AND Task.TaskDate = TaskManagerQrySelect.CalendarDate);
One limitation of this method is that if the date of repetition (e.g. the 15th of each month) is changed, the future records with the wrong day will remain. A solution to this would be to update all the future records with the adjusted date, then run the insert.
One possibility could be to create a table of Months, and a table of Years (prior year, current, and next one). I could run a SELECT query which takes the Day from the TaskManager table, the Month from the Month table, and the Year from the Year table - I imagine that this could somehow create my desired multiple records for a single TaskManager record. Though I'm not sure what the exact SQL would be.