Reputation: 1306
I'm struggling with what appears to be the most complicated SQL query I've ever written!
Database structure:
frog_shared.staff
`ID`, `Firstname`, `Surname`
frog_observations.observations
`ID`, `Teacher_ID`, `Type`, `Main_Positive_Aspect`, `Main_Development_Aspect`, `Grade_for_Behaviour`, `Grade_for_Attainment`, `Grade_for_Teaching`
frog_observations.aspects
`ID`, `Observation_ID`, `Label_ID`, `Type`
frog_observations.aspect_labels
`ID`, `Title`
Sample data:
Member of staff:
`12345`, `Duncan`, `Wraight`
Observation:
`9888`, `12345`, `Formal`, `5`, `7`, `1`, `1`, `1`
Aspects:
`101`, `9888`, `2`, `P`
Aspect labels:
`2`, `Questioning`
What I'm trying to achieve:
I'd like to produce a list of our best teachers in a specific observation aspect. For example, I'd like to see my top 5 teachers for "Questioning".
On top of that, I'd like to filter the data somewhat:
Type=Formal
) and sharing best practice (Type=SBP
) observations should be countedMy attempts:
This statement filters the observations by their grades, but doesn't include any main positive aspects (they weren't included in the original system)
SELECT
CONCAT(s.Firstname, " ", s.Surname) AS `Teacher`,
COUNT( * ) AS Total,
GREATEST(o.`Achievement_Grade`, o.`Behaviour_Grade`, o.`Teaching_Grade`) AS `Worst Grade`
FROM frog_observations.observations o
INNER JOIN frog_shared.staff s ON o.Teacher_ID = s.ID
INNER JOIN frog_observations.aspects a ON o.ID = a.Observation_ID
WHERE a.Aspect_ID = 4
AND ( GREATEST(o.`Achievement_Grade`, o.`Behaviour_Grade`, o.`Teaching_Grade`) BETWEEN 1 AND 2 ) AND o.Datetime > '2011-09-01'
AND a.Type = 'P'
GROUP BY s.ID
ORDER BY `Total` DESC
LIMIT 5
Now the way I'd like to do it is something like this:
SELECT
CONCAT(s.Firstname, " ", s.Surname) AS `Teacher`,
COUNT(mp.*) AS `Number of Appraisal Main Positives`,
COUNT(sp.*) AS `Number of SBP Main Positives`,
COUNT(a.*) AS `Number of Other Positives`,
SUM(`Number of Appraisal Main Positives` + `Number of SBP Main Positives` `Number of Other Positives`) AS `Total`
FROM
`frog_observations`.`observations` o,
( `frog_observations`.`observations` WHERE `Type` = 'Formal') AS mp,
( `frog_observations`.`observations` WHERE `Type` = 'SBP') AS sp
INNER JOIN
`frog_observations`.`aspects` a ON a.Observation_ID = o.ID
GROUP BY s.ID
Unfortunately, other than knowing the headings I want (i.e. number of appraisal main positives
, number of sharing best practice positives
, number of standard positives
and a weighted total
), I have no idea how to write what I presume will be subqueries to get all of this information from a single statement.
Any guidance appreciated.
Input
User wants to view Top 5 members of staff for the aspect Questioning
Process
- Aspect Questioning
has ID 4
in the aspect_labels
table.
- System should then, for each member of staff, count the observations
they have with Main_Positive_Aspect
set to 4
. Some of these observations will be of Type
Formal and some will be of Type
SBP.
- System should also then count the number of rows in the aspects
table for each member of staff where the Aspect_ID
is 4
.
Output
Key:
observations
table where Type
is Formal; GREATEST(Achievement_Grade, Behaviour_Grade, Teaching_Grade) BETWEEN 1 AND 2
; and the Main_Positive_Aspect
is 4
(i.e. Questioning
in the aspects_label
table)observations
table where Type
is SBP and the Main_Positive_Aspect
is 4
aspects
table where Aspect_ID
is 4
for each member of staff (via the o.Observation_ID
-> o.Staff_ID
link)DESC
, by this column.Example output:
-------------------------------------------------------------
| Staff Name FMP SMP Other Points |
|------------------------------------------------------------
| D Wraight 2 1 4 12 |
| A Nother 3 0 0 9 |
| J Bloggs 0 4 1 9 |
| J Arthur 1 1 1 6 |
| M Turner 0 1 0 2 |
-------------------------------------------------------------
Here are the queries, written individually, which work on my database. Basically I need to amalgamate these into one query. If that's possible!
#=======#
# FMP #
#=======#
SELECT
CONCAT(s.Firstname, " ", s.Surname) AS `Teacher`,
COUNT( * ) AS `FMP`
FROM frog_observations.observations o
INNER JOIN frog_shared.staff s ON o.Teacher_ID = s.ID
WHERE o.Main_Positive = 4
AND o.Type = 'F'
AND ( GREATEST(o.`Achievement_Grade`, o.`Behaviour_Grade`, o.`Teaching_Grade`) BETWEEN 1 AND 2 )
GROUP BY s.ID
#=======#
# SMP #
#=======#
SELECT
CONCAT(s.Firstname, " ", s.Surname) AS `Teacher`,
COUNT( * ) AS `SMP`
FROM frog_observations.observations o
INNER JOIN frog_shared.staff s ON o.Teacher_ID = s.ID
WHERE o.Main_Positive = 4
AND o.Type = 'S'
GROUP BY s.ID
#=========#
# Other #
#=========#
SELECT
CONCAT(s.Firstname, " ", s.Surname) AS `Teacher`,
COUNT( * ) AS `Other`
FROM observations o
INNER JOIN frog_shared.staff s ON o.Teacher_ID = s.ID
INNER JOIN aspects a ON o.ID = a.Observation_ID
WHERE a.Aspect_ID = 4
AND a.Type = 'P'
GROUP BY s.ID
Upvotes: 0
Views: 1211
Reputation: 6146
Would something like this work for the initial cut...
SELECT
CONCAT(s.Firstname, " ", s.Surname) AS Teacher,
sum(Case when `Type` = 'Formal' then 1 else 0 end) AS `Number of Appraisal Main Positives`,
sum(Case when `Type` = 'SBP' then 1 else 0 end) AS `Number of SBP Main Positives`,
coalesce(OtherPositives,0) AS `Number of Other Positives`,
sum(Case when `Type` in ( 'Formal' ,'SBP') then 1 else 0 end) + coalesce(OtherPositives,0) AS `Total`
FROM observations o
INNER JOIN staff s ON o.Teacher_ID = s.ID
LEFT JOIN (select Observation_ID, count(*) as OtherPositives) from aspects where Label_ID=4 group by Observation_ID) a ON a.Observation_ID = o.ID
WHERE Main_Positive =4
GROUP BY s.ID
Upvotes: 2