PowerSchool: How to query past enrollment - mysql

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

Related

How to Properly Create a SQL Query

Good Afternoon,
I am working on a database for someone that tracks the vehicles they use in their business. Due to vehicles having new license plates issued to them as they expire the business wants to track the current plate for each vehicle as well as all plates that were previously issued to each vehicle.
I have created a table for vehicles, tbl_vehicles.
I have also created a table for license plates, tbl_license_plates.
Being that each vehicle has multiple license plate records. I need on a form, frm_vehicles, (where certain data for each vehicle is updated) to show only the most recent license plate number to appear. This needs to happen even if the plate has expired...i.e...is no longer valid.
The problem that I am encountering is that I do not have sufficient SQL skills to construct a query that returns for each vehicle only the most recent plate. I wrote the below query and it returns the vehicle_master_id and the expiration date of the most recently issued plate.
However, when I try to add the license_plate_number to the query, it returns every plate that has every been issued for each vehicle. This is a problem because I need the query to return only the most recently issued plate, whether or not it is valid (unexpired).
So, the guidance that I am seeking is how to construct this query so that it returns the license_plate_number for only the most recently issued plate, regardless of validity.
Can someone point me in the right direction, please?
As suggested, here is the text of the query
SELECT tbl_license_plates.vehicle_master_id AS Vehicle, Max(tbl_license_plates.date_expires) AS Expiration_Date, tbl_license_plates.license_plate_number
FROM tbl_license_plates
GROUP BY tbl_license_plates.vehicle_master_id, tbl_license_plates.license_plate_number;
Consider:
SELECT tbl_License_Plates.* FROM tbl_License_Plates WHERE license_plate_master_ID IN
(SELECT TOP 1 license_plate_master_ID FROM tbl_License_Plates AS Dupe WHERE
Dupe.vehicle_master_ID = tbl_License_Plates.vehicle_master_ID ORDER BY date_issued DESC);
More info on subqueries http://allenbrowne.com/subquery-01.html
Another approach is to take your GROUP BY query that has vehicle ID and issue date and INNER JOIN with tbl_License_Plates with compound link on both ID and date fields. This will be a non-updatable query.
Consider using Max function to return max valid date, can find a lot on Google about that function. Something like:
SELECT tbl_License_Plates.vehicle_master_id, Max(tbl_License_Plates.date_expires) AS
MaxOfdate_expires
FROM tbl_License_Plates
GROUP BY tbl_License_Plates.vehicle_master_id;

joining two tables in my sql desn't return a result set

Hi I have run in to a problem when retrieving a particular data set using 3 tables in a MySql database.Tables are as follows
Student
SID | Name | Age | Telephone
Term
TID | Start | End
Payment
PID | TID | SID | Value
SID is primary key of Student table. TID is primary key of Term table. PID is primary key of Payment table. TID and SID in Payment table are foreign key references.
Student table contains data of students. Term table contain data of term start and end dates. Payment table contain data about student payment. Records in Payment table may either contain TID or not. When it is a registration payment there will be no TID. Otherwise it is a term fee and there will be TID. What I want is a list of students that hasn't paid this terms fees until today. Asuume this TID is in a variable. How can I obtain the list of students ? IT SEEMS SUPER EASY. BUT I COULDNT FIND AN ANSWER THIS WHOLE DAY 😣
You want a list of just those students who do not have a TID-populated record whose start and end dates are either side of today, in Payment
SELECT * FROM
student
LEFT OUTER JOIN
(select * from payment where TID is not null and NOW() BETWEEN start and end) this_term_payments
on student.id = this_term_payments.sid
WHERE
this_term_payments.ID is null
There are many ways to skin this cat. Here is one. We filter the payments table down to just a list of this term's payments (that's the inner query). And left join that to students. Left join means we get all students, matched with this_term_payments if the this_term_payments row exists, or NULL in every this_term_payments column if the term payment doesn't exist. The where clause then filters the whole results set down to "just those who don't have a term payment" by looking for those nulls that the left join creates
FWIW, your question attracted close votes because it didn't include example data/demonstrate the level of your effort we like to see on SQL questions. If you'd included sample data for all your tables and an example result set you wanted to see out, it means we can write an exact query that meets your requirements.
This is a bit of a double edged sword for me; we can deliver exactly what you ask for even if you later realise it's not what you want (asking in English is far more vague than giving an example result set) but at the same time we basically become some free outsourced homework contractor or similar, doing your work for you and removing learning opportunities along the way. Hopefully you'll take this query (it's likely it doesn't output everything you want, or outputs stuff you don't want) and craft what you want out of it now that the technique has been explained.. :)
For an SQL question that was relatively well received (by the time i'd finished editing it following up on the comments), and attracted some great answers take a look here:
Fill in gaps in data, using a value proportional to the gap distance to data from the surrounding rows?
That's more how you need to be asking SQL questions - say what you want, give example data, give scripts to help people create your same data so they can have a play with their idea without the boring bits of creating the data first. I picked on that one because I didn't even have any SQL attempts to show at the time; it was just a thought exercise. Having nothing working isn't necessarily a barrier to asking a good question
Try this:
select s.name, p.value from Student s, Term t, Payment p where t.TID = p.TID and s.SID=p.SID and p.TID is null;

MS ACCESS - Finding field for most recent record

Apologies for title, I am not sure how to phrase it.
I currently have two tables "ASSETS" and "LOANS"
ASSETS contains a straightforward list of equipment
It has a field "AssetID" which has a One-To-Many relationship with a field in LOANS called "LoanAssetID"
Each piece of equipment can have many loans. It can be loaned to one person, then returned, then loaned to another. There is a field in "LOANS" named "ReturnDate" in which people record the date that a piece of equipment was returned. There is also a field called "StartDate".
A piece of equipment can said to be currently 'on loan' if the most recent record (that with the most recent start date) has no return date.
However, I am not clear enough in my query writing to complete this. I need to find the most recent record as for any asset, there may be multiple return dates, but these may not always correspond to the most recent loan.
Ideally, I would then like this to calculate a field to mark the equipment as 'on loan' 'available' etc.
Thanks for any help in advance
So far I have tried a Max Query, but, probably due to me misunderstanding queries, I am confused as to why it returns more than one result.
So, currently I have tried
SELECT Max(tbl_Loans.[Start Date]) AS [MaxOfStart Date],tbl_Loans [Return Date], tbl_Loans.LoanAssetID
FROM tbl_Loans
GROUP BY tbl_Loans.[Return Date], tbl_Loans.LoanAssetID
HAVING (((tbl_Loans.[Return Date]) Is Null));
However, what I would like is the most recent value only for any given LoanAssetID; what I get is more than one field for each given LoanAssetID where more than one result exists.
Thank you for your help
The query is grouping by return date, which I don't believe you want. Try:
SELECT Max(tbl_Loans.[Start Date]) AS [MaxOfStart Date],tbl_Loans.[Return Date], tbl_Loans.LoanAssetID
FROM tbl_Loans
GROUP BY tbl_Loans.LoanAssetID
HAVING tbl_Loans.[Return Date] Is Null;
Alternatively, if your system is robust enough to assume that any null return date will correspond with the most recent loan since an asset that has yet to be returned could not be lent to a different individual, you could just search the table for Null return dates:
SELECT tbl_Loans.LoanAssetID
FROM tbl_Loans
GROUP BY tbl_Loans.LoanAssetID
HAVING tbl_Loans.[Return Date] Is Null

Find duplicate between two dates with same Employee ID and same child name in vba access

I have a Form name frmCEA1 and a Table named tabsubCEA. Field names are:
E_ID (which is Employee ID, number field)
FY (which is Financial Year, String i.e. 2014-15)
FChildPrFr ( Which is Claim start Date, Date ( dd-mmm-yy format))
FChildPrupto ( Which is Claim end Date, Date(dd-mmm-yy format))
There are also
four fields in table (tabSubCEA)
EID (which is Employee ID, number field),
FY (which is Financial Year, String i.e. 2014-15),
PeriodFrom ( Which is Claim start Date, Date ( dd-mmm-yy format)),
Periodtill ( Which is Claim end Date, Date(dd-mmm-yy format)).
An employee can process claim single times in a financial Year for single child and he/she can claim for maximum two child. He/She can claim separate for both child or can claim as combined. He/She can also claim for previous financial Year.
I processed claim for an employee for single child in Fin.Year 2014-15 now employee is going to claim his/her second child for same financial year and I processed it successfully.
I want to know that How can my form(frmCEA1) prevent me using (messagebox) if i goes to process claim for same information i.e. same E_ID, First or Second Child with same claim between starting and ending Period.
I tried so much but could not success. Kindly help...
This doesn't necessarily have to be done in VBA, but that is an option. Either way, a query needs to be run to extract the number of records that match a given situation.
When an employee is being processed, run a query against that employee ID within your tabSubCEA table to find the number of records that exist for the desired financial year. However, instead of returning the actual record data, just return the COUNT of the records. If I'm understanding your situation correctly, whenever the COUNT exceeds two, then you don't want to process the employee. The easiest way would be to disable whatever "submit" button on the form.
Your query, whether a created query that references fields on the form, or via VBA would look something like this:
SELECT
COUNT(*)
FROM
tabSubCEA
WHERE
EID = '<employee id here>' AND
FY = '<fiscal year here>' AND
PeriodFrom > '<application date here>' AND
Periodtill > '<application date here>'
This will count the number of records that the employee in question has successfully filed during the desired fiscal year with an active claim period.
Basically, what you're trying to extract from the system is a count of the number of records that meet a specific criteria to this situation. You're going to want something similar to this to validate the number of claims an employee is making.

What is the best way to count rows in a mySQL complex table

I have a table with the following fields (for example);
id, reference, customerId.
Now, I often want to log an enquiry for a customer.. BUT, in some cases, I need to filter the enquiry based on the customers country... which is in the customer table..
id, Name, Country..for example
At the moment, my application shows 15 enquiries per page and I am SELECTing all enquiries, and for each one, checking the country field in customerTable based on the customerId to filter the country. I would also count the number of enquiries this way to find out the total number of enquiries and be able to display the page (Page 1 of 4).
As the database is growing, I am starting to notice a bit of lag, and I think my methodology is a bit flawed!
My first guess at how this should be done, is I can add the country to the enquiryTable. Problem solved, but does anyone else have a suggestion as to how this might be done? Because I don't like the idea of having to update each enquiry every time the country of a contact is changed.
Thanks in advance!
It looks to me like this data should be spread over 3 tables
customers
enquiries
countries
Then by using joins you can bring out the customer and country data and filter by either. Something like.....
SELECT
enquiries.enquiryid,
enquiries.enquiredetails,
customers.customerid,
customers.reference,
customers.countryid,
countries.name AS countryname
FROM
enquiries
INNER JOIN customers ON enquiries.customerid = customers.customerid
INNER JOIN countries ON customers.countryid = countries.countryid
WHERE countries.name='United Kingdom'
You should definitely be only touching the database once to do this.
Depending on how you are accessing your data you may be able to get a row count without issuing a second COUNT(*) query. You havent mentioned what programming language or data access strategy you have so difficult to be more helpful with the count. If you have no easy way of determining row count from within the data access layer of your code then you could use a stored procedure with an output parameter to give you the row count without making two round trips to the database. It all depends on your architecture, data access strategy and how close you are to your database.