I have a table in Access that holds students previous qualifications. It has multiple lines per students dependent on the number of previous qualifications they have. The data has the year of the qualification in it.
I want to create a sub-query that only has the most recent qualification in it (i.e. the latest year). I have tried max and last in the query for the year, but because I am bringing out other fields, it is still pulling out all the qualifications rather than just the latest one.
StudentID Qualificationlevel QualificationType MaxOfYearAwarded
10203 Postgraduate/Masters MSc 2016
10203 Undergraduate BSc 2013
So in the example above, I want to ONLY have the top row being pulled as it is 2016 and therefore later than 2013.
Any help would be appreciated.
Quite a simple task
Just use a subquery as a condition.
To group the query, use a WHERE condition in the subquery. Note that, since we're querying the same table twice, we will need to use table aliases
SELECT *
FROM MyTable t
WHERE t.YearAwarded = (
SELECT Max(s.YearAwarded)
FROM MyTable s
WHERE s.StudentID = t.StudentID
)
Related
I have a access table that has quarterly pricing data starting from 20100131 and goes on as 20100430, 20100731.... 20170131, 20170430. For each pricing date, there are many loans. Some loans stay in the portfolio, some loans are removed and some added for each pricing period. I would like to find the list of loans that exist in all periods and see their price for each period. So i have the "Loan_Number" field and "Price_Date" field. I would like to find the Loan Numbers that exist in all price date points. I appreciate the help.
Thanks!
Would have been nice to see some effort from you but I was intrigued with the challenge so here is what I accomplished.
1 - Need a dataset of all possible combinations of loan numbers and date values. So if you have a LoanNumbers table and a Periods table, create a Cartesian query called AllPairs:
SELECT LoanNumbers.Loan_Number, Periods.Price_Date FROM LoanNumbers, Periods;
If you don't have those tables, generate datasets with queries, assuming the data table has at least one record for every loan number and at least one record for every period:
SELECT DISTINCT Table1.Price_Date FROM Table1;
SELECT DISTINCT Table1.Loan_Number FROM Table1;
2 - Join AllPairs to data table for a 'find unmatched' query called LoanNoPeriod:
SELECT AllPairs.Loan_Number, AllPairs.Price_Date, Table1.Loan_Number, Table1.Price_Date
FROM AllPairs LEFT JOIN Table1 ON (AllPairs.Price_Date = Table1.Price_Date) AND (AllPairs.Loan_Number = Table1.Loan_Number)
WHERE (((Table1.Price_Date) Is Null));
3 - Final query:
SELECT * FROM Table1 WHERE Loan_Number NOT IN (SELECT AllPairs.Loan_Number FROM LoanNoPeriod);
Be aware these type of queries can perform very slowly and with very large datasets might not be practical.
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
How to get Number of Employees Joined or Resigned by Quarterly in SQL
I have a Table called Mst_Employee
fields are
Emp_No, Emp_JoiningDate, Emp_ResignedDate, Emp_Status
Edit: Every half a year, not quarterly.
The easiest way to do analysis like this would be to use the DATEPART function in T-SQL. Assuming all you want is to know a specific quantity for all quarters in all years on your table, an example code would be:
SELECT
DATEPART(YEAR,Emp_JoiningDate) as [Year],
DATEPART(QUARTER,Emp_JoiningDate) as [Quarter],
COUNT(1) as [Emp Count]
FROM Mst_Employee
GROUP BY DATEPART(YEAR,Emp_JoiningDate),DATEPART(QUARTER,Emp_JoiningDate)
ORDER BY 1,2
This will show all the numbers of employee's joined in the quarter. The query can easily be modified to also show resigned employee's in that quarter, or you could use a separate query to show this data.
Just an additional comment, as you're in the Employee Table, you don't need to directly state "Emp_" under all of your attributes.
update employee as a
set a.sup_role=(
select b.job_role from employee as b
where b.supervisorid=a.employeeid
group by b.job_role
order by count(b.job_role) desc
limit 1
)
where a.job_role='MAN1';
OK I have a table of all of our employees - around 100K.
All of our users have job roles that I built based on their employee.job_title. So based on 4K+ job_titles I knock that down to about 40 job_roles. This is so we can assign things in our CMS based on employee.job_roles. This has been working good but the problem is with the managers. The managers get some generic corporate job_title that we role into a generic job_role.
What you see above is code that I use to kind of do what I need to do - find out what job_role a supervisor based on what "most of their employees do". This outputs the correct sup_role but there are several things wrong with my code:
based on my syntax it won't let me update the employee table directly. I have have to update an employee "helper" table and fill in later.
So it is parsing through for the job_role "MAN1". First I don't want to update this to add new manager job roles. Also this doesn't account for my company doing ad hoc things like a manager just have a regular job title or different NULL fields.
And then the last part is that this code is taking 6 minutes to go through. Luckily I run this as a batch job but I am afraid it might cause crashes.
So I have the following table -
employee
with applicable fields
employeeid
supervisorid
job_title
job_role
sup_role
So below is my last attempt. It just runs and never outputs anything. I am wondering if I need to create a helper table to grab the DISTINCT supervisorid's since one employee could be many people's supervisor.
update employee as a
set a.sup_role=(
select b.job_role from employee as b
where b.supervisorid=a.employeeid
group by b.job_role
order by count(b.job_role) desc
limit 1
)
WHERE a.uid IN (select DISTINCT employee.supervisorid
from employee
where employee.supervisorid is not null
);
So, let's say I have a hash/relational table that connects users, teams a user can join, and challenges in which teams participate (teams_users_challenges), as well as a table that stores entered data for all users in a given challenge (entry_data). I want to get the average scores for each user in the challenge (the average value per day in a given week). However, there is a chance that a user will somehow join more than one team erroneously (which shouldn't happen, but does on occasion). Here is the SQL query below that gets a particular user's score:
SELECT tuc.user_id, SUM(ed.data_value) / 7 as value
FROM teams_users_challenges tuc
LEFT JOIN entry_data ed ON (
tuc.user_id = ed.user_id AND
ed.entry_date BETWEEN '2013-09-16' AND '2013-09-22'
)
WHERE tuc.challenge_id = ___
AND tuc.user_id = ___
If a user has mistakenly joined more than one team, (s)he would have more than one entry in teams_users_challenges, which would essentially duplicate the data retrieved. So if a user is on 3 different teams for the same challenge, (s)he would have 3 entries in teams_users_challenges, which would multiply their average value by 3, thanks to the LEFT JOIN that automatically takes in all records, and not just one.
I've tried using GROUP BY, but that doesn't seem to restrict the data to only one instances within teams_users_challenges. Does anybody have any ideas as to how I could restrict the query to only take in one record within teams_users_challenges?
ADDENDUM: The columns within teams_users_challenges are team_id, user_id, and challenge_id.
If this is a new empty table, you can express your 'business rule' that a user should only join one team per challenge as a unique constraint in SQL:
alter table teams_users_challenges
add constraint oneUserPerTeamPerChallenge
unique (
user_id
, team_id
, challenge_id
);
If you can't change the table, you'll need to group by user and team and pick a single challenge from each group in the query result. Maybe pick just the latest challenge.
I can't test it, but if you can't clean up the data as Yawar suggested, try:
SELECT tuc.user_id, SUM(ed.data_value) / 7 as value
FROM entry_data ed
LEFT JOIN
(
select tuc.user_id, tuc.challenge_id from teams_users_challenges tuc group by tuc.user_id, tuc.challenge_id
) AS SINGLE_TEAM
ON SINGLE_TEAM.user_id = ed.user_id AND
ed.entry_date BETWEEN '2013-09-16' AND '2013-09-22'
WHERE tuc.challenge_id = ___
AND tuc.user_id = ___