Finding if Any date in a table is between 2 dates - sql

I have a SQL query where I need to find out if any date in a table relating to a specific client is between another date in a different table and that date plus 5 days
I have a table with a list of client details (client table) with the fields clients name, address and ID (PK) in it
I have a table with the annual assessments details where we review the clients account (assessment table) with the fields assessment date and assessment ID (pk) in it
I a separate table with a list of the dates we have spoken with the client (meeting table) with the fields Meeting name (eg meeting type 1, meeting type 2, meeting type 3) meeting date, meeting ID (PK)
We can see the clients a lot of times during the year for different meetings, however I need a query that will tell me Yes or No, has the client been spoken to with 5 days of the annual assessment.
So I need something like the below
Select
Client_ID (PK) (from client table)
,Client_Name (from client table)
,Assessment_ID (PK) from assessment table
,Assessment_date (from assessment table)
Then here I need something here that will say, CASE WHEN from all of the dates in the meetings table relating to this client, are any of them within 5 days of the assessment date if so 'Y' if not 'N'
I'm fine with joining all the relevant table as and when required it's just the query for any date in the meeting table between assessment date and assessment date + 5 that I am struggling with.
Any help, greatly appreciated.

Something like this.
SELECT CustomerData
,CASE
WHEN DATEDIFF(DAY, MeetingDate, GETDATE()) < 5 THEN 'Yes'
ELSE 'No'
END AS CustomerConsultedLastFiveDays
FROM CustomerMeetingTable
WHERE Conditions = Conditions;

it's interesting to pay attention to some points:
If the Customers table has a relationship with the evaluation table, if so you can make an inner join between the two, finding what evaluations have for an X customer.
If you already have this relationship now, do an inner join, Exists or IN to validate if Client X exists in the Meeting table.
If it is not possible to make this relationship by PK, it is a problem regarding the structure of the data, since without reference to the customer in the meeting table, I did not find a way to make this relationship in your text.
Assuming you've done everything I mentioned above just make a CASE for your code
for example:
Note: I didn't quite understand the filter point related to the dates of the two tables, so I left the WHERE like this,
Graciously.

Related

Select records even if doesn't exists

I have database with 4 tables:
First table represents rooms and has single column called "RoomNumber".
Second table is Hours and has single column "HourNumber".
Third table is Days and has two columns "DayNumber" and "DayName".
Last table is TimeTables of rooms and it's a relation table between the three other tables.
The last table has the following columns:
RoomNumber
DayNumber
HourNumber
Subject (what's happening at the specific hour and day)
but this table stores only records with rooms that has Subject (it keep only busy hours of rooms), it doesn't presents records with empty subjects so it can't show me when a chosen room is available (no subject means the room is clear).
I want to somehow write a query that will give me the status of all the rooms in a specific day and hour.
For example this query returns all the busy rooms at day 1, hour 1:
SELECT *
FROM TimeTables
WHERE HourNumber = 1 AND DayNumber = 1
But I want to get the status of all the rooms at the specific time, I know the rest of the records doesn't exists.
Is there a way to do something like that?
If you want the status of the rooms in MS Access, I think a correlated subquery is the simplest method:
select r.*,
(select tt.subject
from TimeTables as tt
where tt.RoomNumber = r.RoomNumber and tt.HourNumber = 1 and tt.DayNumber = 1
) as subject_1_1
from rooms as r;

I am trying to write a SQL Server query using joins and having some difficulty

Tables are explained in detail as below:
I have 3 tables:
Table A:
It serves as the master table for information about the employees.
EmployeeId(Primary key)
Employee Designation
EmployeeName (More columns of employee data which is not relevant to this particular query)
Table B:
It serves as table where all employees who are accounted for are stored. For ex an employee who has reported sick or is on leave or has pregnancy leave, etc. Bottom line an employee which is not available
EmployeeID (primary key) (also referencing master table A as foreign key)
AccountedFor
AccountedFordurationFrom (datetime)
AccountedForDurationTo (datetime)
Table C:
It serves as a table where excused data of employees are present. For ex we have our organization's time table spread as events, 1st event is morning time conference, then 2nd is silence working time, 3rd is brainstorming sessions etc. Now if an employee is excused for a particular event, it is entered here.
EmployeeID
EventCode
Excuse_DurationFrom
Excuse Duration To
Any specific details
Here EmployeeID and ExcusedForEventCode are both composite primary keys as it is possible to have same employeeId for multiple excuses,but the combination is always unique.
We have built some custom attendance management system and would require the following details:
We need to find all those employees who are neither accounted for nor excused for a specific event(this will be provided through front end) for a time duration selected through the front end.
The result of the above query will subsequently be used to compare with a biometric attendance machine logs which gives
EmployeeId|LogDate(datetime)|EventCodes as a separate table input to our database (Master table A employeeId references this EmployeeId as foreign key)
It will be compared to find out true absentees for a particular event. ie All those employees who are neither accounted for, nor excuses for any particular event and who does not figure out in the biometric scan machine logs are absented for those time duration selected. We need the output of absentee like this EmployeeId|Employee Designation|Employee Name|EventName (have a separate table linking with EventCode)|Date&time (this would be per day per event report of employee who are absent from the selected time duration).
We have tried queries like:
select
employeemastertable.employeeid,
employeemastertable.Designation,
employeemastertable.Name,
EventCodes.EventCodeName as Eventexcusedfrom
from
employeemastertable
inner join
employeeexcusedforevents on employeemastertable.employeeid = employeeexcusedforevents.employeeid
inner join
EventCodes on employeeexcusedforEvents.ExcusedForEventCode = EventCodes.Eventcode
left join
employeeaccountedFor on employeemastertable.employeeid = employeeaccountedFor.employeeid
where
employeeexcusedforevents.ExcusedForEventCode != 1 (Morning conference)
and employeeaccountedFor.employeeid is null;
Names have been changed
I do understand this will give those employees who does not figure out in event Morning conference but even if I do left join instead of inner join between employeemastertable and employeeexcusedForevents and put employeeexcusedforevents.excusedforeventcode is null and employeeexcusedforevents.employeeid is null, I do get all those employees not present in the other two table, but the criteria of event is not satisfied. That means what if the employee is excused for the 2nd event as well in the organization. How would I cater for that in the above code? (PS this is only the 1st part of the equation I understand that, after this I need help for the other part also, where time duration and comparing with logs is concerned)?
I assume there will be just one row for the EventCode=1 in table EventCodes. Below I cross join the wanted event to the employee master table and then exclude any employees that are excused or accounted for.
-- employees neither accounted for nor excused for a specific event
SELECT
em.employeeid
, em.Designation
, em.Name
, ec.EventCodeName AS Eventexcusedfrom
FROM employeemastertable em
CROSS JOIN (
SELECT Eventcode, EventCodeName
FROM EventCodes
WHERE Eventcode = 1
) ec
WHERE NOT EXISTS (
SELECT NULL
FROM employeeexcusedforevents ee
WHERE em.employeeid = ee.employeeid
AND ec.Eventcode = ee.ExcusedForEventCode
)
AND NOT EXISTS (
SELECT NULL
FROM employeeaccountedFor eaf
WHERE em.employeeid = eaf.employeeid
)
;

SQL Querying Help/IF Conditional Statement

So I am creating a booking table. I have two drop down lists called Date and Time and the data for these is being retrieved from a table called "DateTime" with a field called Date with a load of dates in it and same with time.
This booking system is booking time and a date with a Doctor. I'm lost at this point in terms of how do I get times to only appear for a doctor that the user wants to choose an appointment with to avoid double bookings. If a user has booked 9:15am on a certain date, I don't want that time to appear for another user for that date and doctor.
UPDATE Once a user has selected their date time and doctor, this is stored in a table called Booking. So i was originally going to delete that time and date out of that DateTime but this will then not appear for another doctor if selected.
HELP PLEASE. :'(
At least you should share your own table design.
I think there will be two table.
One Master table (booking master table)
--date
--time
--isactive
Another one
doctor booking table
--date
--time
--doctorid
--patientid
--isActive (0,1)-- 0 in cae of cancel
So in GUI I select Doctor and Date,I pass this doctorid and date to my proc
It fetch me date,time etc from proc.which help me to populate calender.
I populate calender for each doctorid and date.
So I have written this on doctor and date change both.
Now while creating Calendar,if I get already book flag then I will show this time,but it will be disable.
My query will be like this
select bm.date,bm.time
,case when db.date=dbm.date then 1 else 0 end isBookedDate
from BookingMaster BM
left join DoctorBookingMapping DBM
on bm.date=dbm.date
where dbm.isactive=1
and db.isactive=1
and dbm.doctorid=#Doctorid
and db.date=#Date
You can do that with a query without deleting data from your DateTime table.
SELECT dt.[Date], dt.[Time], dt.Doctor
FROM dbo.[DateTime] dt
WHERE NOT EXISTS ( SELECT 1
FROM dbo.Booking b
WHERE
b.[Date] = dt.[Date]
AND b.[Time] = dt.[Time]
AND b.Doctor = dt.Doctor)
The query selects all the dates and times that does not currently exist in your booking table.
Hope this helps.
Marius

Writing a specific SQL query

I have a database which saves data from a survey where one person can take survey one or two times, and not more than that. I have a column DATE through which I want to get all peoples first survey(not second one).
For example, the person with EMAIL shane#gmail.com has given survey on DATE 29th and 30th of December. Same way person with EMAIL mike#gmail.com has given survey on DATE 1st nov and 28th dec.
I want to get both persons first survey records. Thank you
Without the schema it's difficult to guess at what you need. But if it's as simple as a table with email and survey dates it could be something like this:
select email, survey_date
from myTable
group by email
order by survey_date asc
You can cross the table with itself
select * from table t1 join table t2
on t1.email = t2.email
and t1.surveydate < t2.surveydate
PS: you can optimize the query with a clause "WITH", if your database engine supports it. This query will work correctly as long as there only 2 records for each email as you have exposed

Oracle Select Highest date per record

I'm a little bit stumped as to how to do this. I want to select records from a table "agency" joined to a table "notes" on an id column that the two tables share.
Table structure:
create table notes (
notes_id varchar2(5),
agency_gp_id varchar2(5),
call_date date,
call_note varchar2(4000)
);
create table agency(
agency_id varchar2(5),
agency_name varchar2(5),
street varchar2(75),
city varchar2(50)
);
alter table notes add constraint "fk_group_notes_agency_id" foreign key(agency_gp_id)
references agency(agency_id) enable;
-Each table has auto-numbering, "before-insert" triggers so the id numbers stay in synch (along with other stuff in the case of adding a note to a newly created agency) - everything I need it to do (the databse), it does.
-Each record from the agency table has a distinct name/address combo (with different branches in different cities) and each record from the notes table has a date entry corresponding to each agency.
-Each agency can have multiple notes (multiple note details from subsequent visits)
What I am attempting to do is select each (distinct agency,street,city) that has not had a note added to it within the past four months.
This is the query I came up with:
SELECT count(a.agency_name) as number_of_visits,
a.agency_name,
(a.street||', '||a.city) as "Location",
n.call_date,
ROUND(TRUNC(sysdate - call_date)) AS days_since_visit
FROM notes n, agency a
WHERE (sysdate - n.call_date) > 120
AND n.agency_gp_id = a.agency_id
--AND a.city = 'München' --not necessary, used for limiting number of results
GROUP BY n.call_date,a.agency_name,a.street, a.city
ORDER BY a.agency_name ASC, n.call_date desc;
It kind of works...I can see what I want but I also see what I DO NOT want (e.g. the multiple notes on each agency). The only thing I want to see is the last entry (most recent, according to the WHERE clause) of each agency. The picture I want to create is: For whichever agency that has not been annotated within 120 days of the last note, display the address and name and the last note date.
(Instead of showing the number of days since EACH visit, I want to show the number of days that have past since the LAST visit - per distinct agency,street,city).
This is for an app that will help a sales executive schedule her sales calls and is run twice a week. I have been unable to figure this out. Also, bear in mind that the actual tables used are much more descriptive - what I have used here are only the parts I need to describe the question.
I would appreciate any suggestions on how to solve this problem.
Thanks!
If I understand your problem correctly, changing call_date to MAX(call_date) (and removing it from the GROUP BY statement) should get you what you want int terms of data, but would also pull in false positives, namely any agency that had notes older than 120 days, regardless of the most recent note. If we filter those agencies out in a NOT EXISTS subquery, that should get you where you need to go.
SELECT count(a.agency_name) as number_of_visits,
a.agency_name,
(a.street||', '||a.city) as "Location",
MAX(n.call_date),
ROUND(TRUNC(sysdate - MAX(call_date))) AS days_since_visit
FROM notes n, agency a
WHERE (sysdate - n.call_date) > 120
AND n.agency_gp_id = a.agency_id
AND NOT EXISTS (SELECT 1 FROM notes n2
WHERE n2.agency_gp_id = a.agency_id
AND (sysdate - n2.call_date) <= 120)
--AND a.city = 'München' --not necessary, used for limiting number of results
GROUP BY a.agency_name,a.street, a.city
ORDER BY a.agency_name ASC, MAX(n.call_date) desc;