SQL Querying a Database Using The Current Date and Date associated with an Attribute - sql

I am trying to query a from scratch database I created. For each job posting in my database, I store the date of which it was posted in the 'date' datatype, which is in the format of "DD-MON-YY". I want to know which job postings haven't been filled after one month after its posted date.
So far I can query my database and find which jobs haven't been filled, due to a particular attribute being null in my table. But I don't know how to add the condition that it has been at least one month.
SELECT JOBID
FROM JOB
WHERE HIRED IS NULL;
For reference I have created this database in Oracle, and am using SQL developer.

I guess to rephrase, how would I make that condition, would I add one month to the date stored and the compare it with today's date?
Compare your date column to the current date with -1 months added to it:
SELECT JOBID
FROM JOB
WHERE HIRED IS NULL
AND date_column <= ADD_MONTHS(SYSDATE, -1);

Related

Need help to fetch rows from oracle DB based on timestamp

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.

Query changed records in SQL using a created / modified time stamp column?

I'm trying to query my SQL Server 2008 R2 database to find out records that were put into a cancelled state during a given time period. Each record consist of one row in the database with a Created By timestamp, and a modified by timestamp. I can't change the schema of the database.
Each record has a "cancel state" column that is set to 0 or 1 (N and Y). I need to run a nightly job/query that will show all of the cancelled records from the day.
Simple enough, when the record is cancelled the modified timestamp is updated, so my query looks like
SELECT *
FROM mytable
WHERE CONVERT(DATE, a.modified_timestamp) = CONVERT(DATE, CURRENT_TIMESTAMP)
AND cancel_flag = '1'
The issue I am running into, if any other data is modified in the record, the timestamp is updated so the query will give me duplicate results if some other value in the row is changed. Is there an easy way to do this without changing the schema or adding my own table for tracking?

Oracle query to fetch data based upon a order without using order by

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.

How do I Automatically insert monthly records into a table via SQL?

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.

Determine how long a customer has been in a database table

I have a customer table and the only column I have to work with is the date column. The customer's record is inserted into this table and only removed from it upon a certain action. I am trying to figure out a query that would show me exactly how long said customer has been in this table using only a date field.
This will tell you how many days each record has been passed since the date indicated in your DateField:
select dateDiff(day, DateField, GetDate()) from YourTable
For more information, read more about DateFiff