NOT IN use in same table - mysql

im kinda new to the site, as a user atleast, been finding my answers in here for a long time :)
My problem is this, i work at a rather big hospital, where we run a mysql db containing all our employees, and now i need to make a query that can show my all employees who's employment ended during 2017. The thing is, since its a big hospital where ALOT of departments alot of the employees change jobs internally between the different departments, and everytime they do a new row in the table is created with their new employment details.
in every row for every employment, it contains their employer ID, the start date and end date, and some other info. the end date, can be either a date ofc, it can be NULL or 0000-00-00, the last 2 indicates that their imployment has no end date.
So its easy enough to do a simple search containing all users with and end date containing 2017
(SELECT * FROM table WHERE enddate LIKE '%2017%')
and it gives me all the users who has an end date in 2017, problem is ofc, that it does not account for users who might just have switched department, and has ended its employment in one department to start in another.
So what im trying to do is get all users with a 2017 enddate and then all people that has no enddate or and enddate after 2017 and then remove them from the list of people with an 2017 enddate.
i tried the following:
SELECT *
FROM users
WHERE enddate LIKE '%2017%' AND employid NOT IN
(
SELECT * FROM users WHERE enddate LIKE '%0000%'
);
i know it doesnt really over all i wanted, but at first i was really just trying to get the NOT IN to work in some way, and then after that work my way on to include the rest, but i cant even get that to work.
I tried searching for some uses of NOT IN, but it seemed to always be some very simple uses of them and always on 2 different tables.
I hope i explained it correct, as stated im still kinda new to mysql and sql in general :)

To solve the NOT IN Problem you can use this query:
SELECT * FROM users
WHERE enddate LIKE '%2017%' AND employid NOT IN
( SELECT employid FROM users WHERE ansslut LIKE '%0000%' );
Note that inside the NOT IN Select you must specify the "employid" field.
See if this work for you

You are matching for a column and the you shoul return a comparable value from the subselect related to NOT IN
eg asssuming you emp_id match with user id from you r subselect you should
SELECT *
FROM users
WHERE enddate LIKE '%2017%'
AND employid NOT IN (
SELECT user_id FROM users WHERE ansslut LIKE '%0000%'
);

Related

PowerSchool: How to query past enrollment

I know this is somewhat of a specialized question since only a small percentage of members will even have heard of PowerSchool, but it's hard to find help for this. Given a start date and end date, I need to run a query that will return the student ID's for all students who were enrolled in the District during that time period. If I could use that with 'WITH AS', I could add it to an attendance query 'Where' clause like below. This is what I've got so far, but I don't know how to check it's accuracy:
SELECT * FROM Students
WHERE ID IN (
SELECT studentid FROM ps_adaadm_defaults_all
WHERE schoolid IN ('16', '28', '40')
AND calendardate >= '1-May-15'
AND calendardate <= '31-May-15'
GROUP BY studentid)
ORDER BY LastFirst;
"ps_adaadm_defaults_all" is a PowerSchool View that is mainly for ADM so my assumption here is that if a student ID exists in ps_adaadm_defaults_all with a date between the two given dates, that student was enrolled at least that day regardless of attendance, correct? Any PowerSchool users out there that can lend a hand?
I get results with this query but when I try to verify the accuracy by using the PowerSchool site, the results aren't exactly the same. What I mean by using the site is I log in as district admin, set Term to 15-16 year, School to desired school and select students whose last names begin with 'A'. I then start comparing the list it provides with the students from the query results whose last names begin with 'A'. I am noticing though that there are names that I get with my query that are not showing on the site and I think it's due to their exitdate being prior to the current schoolyear. Those students were obviously enrolled at that time, but their names aren't in the PowerSchool results. I'm thinking because they're not enrolled anymore? Is there any way for me to test the accuracy of this query? Am I even on the right track? Thanks in advance.
It sounds to me like you have two questions:
What is the best query to return all students who were enrolled during a given time period?
What is the best way to check that my query is selecting all records it should be?
I'd use the ps_enrollment view for your query. It includes student id, school id, and start and end dates, so it can be used to find all students who were enrolled at a certain point in time.
Students enrolled for the whole specified time period
SELECT UNIQUE pe.StudentID
FROM ps_enrollment pe
WHERE pe.schoolid IN ('16', '28', '40')
AND pe.EntryDate <= '05/01/2015'
AND pe.ExitDate >= '05/30/2015'
Students enrolled at any time within the specified time period
SELECT UNIQUE pe.StudentID
FROM ps_enrollment pe
WHERE pe.schoolid IN ('16', '28', '40')
AND (
(pe.EntryDate <= '05/01/2015' AND pe.ExitDate >= '05/01/2015')
OR (pe.EntryDate <= '05/30/2015' AND pe.ExitDate >= '05/30/2015')
OR (pe.EntryDate >= '05/01/2015' AND pe.ExitDate <= '05/30/2015')
)
In the above example, the three conditions inside the AND check for enrollments that either started before or on and ended after or on the first date, then the second date, and finally checks for any enrollments that happened in between the two dates.
Note: I used UNIQUE instead of GROUP BY. I think it fits what you're doing a little bit more.
The easiest way to check these numbers in the admin side is to use System Reports -> Membership and Enrollment -> Enrollment Summary by Date. This is an easy way to check enrolled students numbers at any point in time, and also will give you the list of those specific students. It includes inactive students.
You can double-check that it's working perfectly by entering a single date in your query instead of using a date range, and by checking that date against the Enrollment Summary by Date. When I did this for our district, my query pulled 7 extra records (out of over 7000), but upon investigation, all of those were due to bad reenrollment records, so it appears to be working correctly.
When you search PowerSchool from the admin website, it only returns active students regardless of what term you select. In other words, I can't select "2000-2001" from the terms list and magically have everything reflect that term.
I can think of a couple things that may be affecting your searches:
search by using a forward slash to include inactive students "/lastname"
if you are searching HS students - remember that seniors transfer to a special school when they graduate
A better way to verify your query results would be to use the ADA/ADM section under System Reports. Reduce your query to one date and then run the ADA/ADM by Date report for the same day.
Just came across this and for anyone that is reading through this, PowerSchool has come up with "as of" selections.
Examples:
*as_of=09/30/2020;enroll_status=0
*as_of=09/30/2020;track=D

Using Delete, Update, Insert in MySQL

Good day!
First of all, I am new at MySQL, and I've got some problems with altering tables with query's.
Secondly, sorry for bad English, unfortunately, it's not my native language.
So yeah, I have some questions, and I will be very thankful if you will be able to help me.
I have 2 tables: Screenshot
Foreign key is 'manufact' from table Registred
So, I have few Query tasks I wanted to do, but can't figure out how to do them.
Here goes first task I did, I just want you guys to check, If I did it right.
Calculate fields from January and February where Car Manufacturer is VW.
SET Total = January + February WHERE Manufact = 3;
And here comes Query's I can't do:
Delete all information about car manufacturer, that had smallest amount of cars registred in January.
Here is what I came up with.
DELETE FROM Registered Order by January Limit 1;
But it didn't delete information from table 'manufacturer'.
What can I do there?
Here is hardest one so far:
Calculate all cars registered in January and February and save it in additional field. (Should be displayed as Int, without floating point.)
Code:
ALTER TABLE Registered Add Column alltotal Int;
UPDATE Registered
Set alltotal = Select SUM(February + January) From Registered;
What I wanted to do is, Create only 1 field, where Sum of all February and January fields will be calculated.
Any suggestions so far?
P.S If I will be able to do these, I will be able to complete other tasks myself :)
P.S.2 I am new here, so please sorry for bad Question editing. I am doing as in tutorial I found but it's hellish for me. I tried my best :)
Let's break this down problem by problem. The first one is:
Delete all information about car manufacturer, that had smallest amount of cars registered in January.
The first thing we need to do is write a subquery that determines which manufacturer that is. We can do so by selecting the id of the row in registracija with the minimum value for January. We can do that using ORDER BY, which you caught on to:
SELECT vieglas
FROM registracija
ORDER BY january
LIMIT 1;
Now that we have that id, we can delete from that table using the WHERE clause:
DELETE FROM registracija
WHERE vieglas = (SELECT vieglas FROM (SELECT * FROM registracija) t ORDER BY january LIMIT 1);
For information on why I included the SELECT * FROM registracija, see this answer.
To see an SQL Fiddle of that in action, check this: http://sqlfiddle.com/#!9/c81d5/1
For the second part:
Calculate all cars registred in January and February and save it in additional field. (Should be displayed as Int, without floating point.)
We can use the addition operator along with an update command to put this total inside the Total column like this:
UPDATE registracija
SET total = (january + february);
For the SQL Fiddle of the update, see this: http://sqlfiddle.com/#!9/f5b28/1
for deleting all record which has had smallest amount of cars registred in January delete from 'Registracija' where 'January' =select min('January') from Registracija
Try following:
1) Total Count For January & February
SELECT (January+February) AS TOTAL from Registrant where Vieglas = 3
2) Delete Query
DELETE FROM Registrant INNER JOIN Vieglas Order By Registrant.January Limit 1

SQL select the available rooms by date cheking

I have in my database a table called rooms that contain the rooms information and property ,and another table called reservation table that contain the Room Reserved, FromDate and ToDate .
What i want to do is to make the user pick room size that he want to reserve and pick the date for reserving the room ,then i provide for him the available rooms depend on the Room Reservation table.
here what i did:
SELECT * FROM Rooms,Reservations WHERE
Rooms.R_Size = 'roomSize' AND ('4/19/2013' NOT
BETWEEN Reservation.FromDate AND Reservation.ToDate AND '4/19/2013'
NOT BETWEEN Reservation.FromDate AND Reservation.ToDate)
The problem its return to me duplicate's rooms and even if its between the reserved date in specific reservation but its not between reserved date in another reservation still it will return it to me.
What i want is to check if the room is reserved at the same or between a specif date and if it is i don't want it to be selected and returned at all.
Thanks.. and sorry for my poor english
There are two problems with your query. One is that there is no condition on the join between rooms and reservations, such that rooms of the correct size will be returned once for each reservation satisfying the date tests. Another problem is that your date test is wrong as it will not detect existing reservations that is completely within the date interval of the new reservation.
A query like this one should give you the result you want:
SELECT * FROM Rooms
LEFT JOIN Reservations
ON Reservations.R_Number = Rooms.Number
AND Reservations.ToDate > '4/19/2013'
AND Reservations.FromDate < '4/20/2013'
WHERE Rooms.R_Size = 'roomSize'
AND Reservations.R_Number IS NULL
It works by joining the rooms to the reservations for that room, and then selecting the rooms for which there are no reservations that conflicts with the new reservation being made.(Old reservation that ends before the new one starts, or that starts after the new one ends are no problem).
What you are doing here is a cross join. Every row from table a (Rooms) is joined with every row in table b (Reservations).
In order to make your query work, you need to specify that Rooms.Rooms_Key = Reservations.Rooms_ForignKey in your where clause (or an explicit join [inner,left,right] and specify the ON fields as they are easier to read in my opinion - explicit-vs-implicit for more info).
Once you have converted the join type, the where clause will start to give you better results, and you should be able to modify it if you still need to at that point.

How to display the first and second Doctor to see a patient?

I have to create a table where there are lots of columns pulling date from one table and two views. To display the columns is no problem. The problem comes into play when I have to alias two columns to show a patient who received services from the first two distinct doctors (doctor_1 and doctor_2). Each doctor has their own ID. I’m not sure if I should use the “distinct top (2)”, “rank”, etc… Here is what it sort of looks like.
Date, LastName, FirstName, Address, City, State, Zip, Hostital, Room, Doctor_1,Doctor_2
Any help would be greatly appreciated.
Let's assume your table looks something as follows:
doctor_patients:
doctor_id int,
patient_id int,
visit_date datetime
In that case you can write a query similar to the following:
select a.patient_id, b.doctor_id as doctor_1, b.visit_time_max as doctor_1_visit_time, a.doctor_id as doctor_2, max(a.visit_time) as doctor_2_visit_time
from doctor_patients a
inner join
(select patient_id, doctor_id, max(visit_time) as visit_time_max
from doctor_patients
where visit_time < a.visit_time
and patient_id = a.patient_id
and doctor_id = a.doctor_id) b
You can always put a where clause at the tail end and apply filters to the "a" table. I am not sure if this query will run as-is because I did not try it out on SQL. But I hope this gives you a general idea about what you need to do. There might be better ways to accomplish this using latest SQL features but this should get you rolling. I hope this is the answer you were looking for!

Query Construction Combining UNION and LEAST

I have an email subscription table and a user table. I need to combine the two to get all the emails, since it's possible to create an account without subscribing and vice versa. Easy enough so far:
SELECT email FROM emailcapture
UNION
SELECT email FROM cpnc_User
Now, this gets me the complete list of all emails. For each email on this combined list, I need to add an extra piece of information: the created date. Both emailcapture and cpnc_User tables have a "created" field. The created date should be the earlier of the two dates, if both dates exist, or, if only one exists and the other is NULL, it should just be the one that exists.
How can I change this query so that it returns this extra piece of information, the created date? Keep in mind that the new query I seek should return exactly the same number of rows as the query above.
Thanks,
Jonah
SELECT i.email, MIN(i.date_creation) FROM
(SELECT email, date_creation FROM emailcapture
UNION ALL
SELECT email, date_creation FROM cpnc_User) as InnerTable i
GROUP BY i.email