SQL lag window and custom logic [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am working on this dataset
https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=447a5d2c33b04346e70dab0a8d098655
Custom logic:
Grouped by name, testcentre, coursename, testtype.
If a retest is taken, then scores are compared - if higher the highest one precedes or original score.
Lag:
Based on above selected row, if a lag window exists between the remaining set of records example within 4 days , then the higest score record shall be picked up.
Any suggestions is appreciated.
Sample data
+----------+-------+------------+------------+----------+-----------+------------+------------+------------------+-----------------------------------------------+
| recordid | Name | testcentre | coursename | testtype | testscore | testdate | retestflag | Preferred_Output | RejectReason |
+----------+-------+------------+------------+----------+-----------+------------+------------+------------------+-----------------------------------------------+
| 1 | Sam | Paris | English | IELTS | 90 | 01/02/2019 | 0 | 0 | |
| 3 | Sam | Paris | English | IELTS | 95 | 02/02/2019 | 1 | 1 | Better score in retest |
| 4 | Sam | Paris | English | TOEFL | 80 | 04/02/2019 | 0 | 0 | Within 4 days of previous test |
| 21 | Sam | Paris | English | IELTS | 95 | 02/02/2018 | 1 | 1 | marked as retest without base.needs inclusion |
| 5 | Jack | London | English | IELTS | 90 | 01/02/2019 | 0 | 1 | Same or bad score in retest |
| 8 | Jack | London | English | IELTS | 90 | 02/02/2019 | 1 | 0 | Same or bad score in retest |
| 7 | Louis | Brazil | English | IELTS | 70 | 01/02/2019 | 0 | 1 | Same score in retest |
| 11 | Louis | Brazil | English | IELTS | 70 | 02/02/2019 | 1 | 0 | Same score in retest |
| 13 | Louis | Brazil | English | TOEFL | 100 | 04/02/2019 | 0 | 0 | Within 4 days of previous test |
| 55 | Sam | Paris | English | IELTS | 90 | 01/02/2016 | 0 | 1 | Older test, no follow on |
| 60 | Sam | Paris | English | IELTS | 95 | 01/08/2019 | 0 | 1 | same score in retest |
| 61 | Sam | Paris | English | IELTS | 95 | 02/08/2019 | 1 | 0 | |
| 62 | Sam | Paris | English | TOEFL | 80 | 04/01/2020 | 0 | 1 | More than 4 days, included |
+----------+-------+------------+------------+----------+-----------+------------+------------+------------------+-----------------------------------------------+
Desired Output
+----------+-------+------------+------------+----------+-----------+------------+------------+------------------+
| recordid | Name | testcentre | coursename | testtype | testscore | testdate | retestflag | Preferred_Output |
+----------+-------+------------+------------+----------+-----------+------------+------------+------------------+
| 3 | Sam | Paris | English | IELTS | 95 | 02/02/2019 | 1 | 1 |
| 21 | Sam | Paris | English | IELTS | 95 | 02/02/2018 | 1 | 1 |
| 5 | Jack | London | English | IELTS | 90 | 01/02/2019 | 0 | 1 |
| 7 | Louis | Brazil | English | IELTS | 70 | 01/02/2019 | 0 | 1 |
| 55 | Sam | Paris | English | IELTS | 90 | 01/02/2016 | 0 | 1 |
| 60 | Sam | Paris | English | IELTS | 95 | 01/08/2019 | 0 | 1 |
| 62 | Sam | Paris | English | TOEFL | 80 | 04/01/2020 | 0 | 1 |
+----------+-------+------------+------------+----------+-----------+------------+------------+------------------+

Based on your sample data and description, this seems to do what you want:
select t.*
from (select t.*,
row_number() over (partition by name, testcentre, coursename, testtype order by testscore desc) as seqnum,
count(*) over (partition by name, testcentre, coursename, testtype) as cnt
from test t
) t
where seqnum = 1 and cnt >= 2;
This does not include the condition on "within 4 days", because that condition is not clearly explained. What happens if there are a series of 5 tests, each 3 days apart, for instance?

select * from (
select *, row_number() over (partition by name order by testscore desc) rn
from test
) t
where rn = 1
Fiddle

Related

How to Compare one row with other rows in SQL

I have a data set that consist of team members.
I want to calculate the Average of only member 2.
However, there are conditions for the calculation to meet like,
for example, id 1 have Anna and Sam working together, I want to calculate only for member2 which is Sam
For that, I want to sum the score of the ID's that have
Sam working with him self like id:2 member1:Sam member2:Sam
Sam working with other member but not Anna(member1) like id:3 member1:Sam member2:Nihal OR id:4 member1:Nihal member2:Sam
Then divide by distinct #ID
Input
+----+---------+---------+-------+
| ID | member1 | member2 | score |
+----+---------+---------+-------+
| 1 | Anna | Sam | 10 |
| 2 | Sam | Sam | 30 |
| 3 | Sam | Nihal | 40 |
| 4 | Nihal | Sam | 50 |
| 5 | Sam | Anna | 20 |
| 6 | Anna | Anna | 60 |
| 7 | Nihal | May | 70 |
| 8 | May | May | 80 |
+----+---------+---------+-------+
Output
+----+---------+---------+-------+-----+
| ID | member1 | member2 | score | AVG |
+----+---------+---------+-------+-----+
| 1 | Anna | Sam | 10 | 40 |-->AVG= 30+40+50/3
| 2 | Sam | Sam | 30 | 30 |-->AVG= score
| 3 | Sam | Nihal | 40 | 70 |-->AVG= 70/1
| 4 | Nihal | Sam | 50 | 20 |-->AVG= 30+10+20/3
| 5 | Sam | Anna | 20 | 60 |-->AVG= 60/1
| 6 | Anna | Anna | 60 | 60 |-->AVG= score
| 7 | Nihal | May | 70 | 80 |-->AVG= 80/1
| 8 | May | May | 80 | 80 |-->AVG= score
+----+---------+---------+-------+-----+
Try the following:
select t1.*,q.avg_score
from yourtable t1
cross apply
(
select avg(score) as avg_score
from yourtable t2
where
t1.member2 in (t2.member1,t2.member2)
and t1.member1 not in (t2.member1,t2.member2)
)q

windowing functions ms access

I am working on a class scheduling database in MS Access. There are a variety of classes, each of which is taught multiple times, sometimes multiple times in a day, but not necessarily every day. Each course has a unique set of software and data that is stored on a laptop. there is a set of laptops for each course with that software loaded.
For any given training day I need to assign a range of laptop IDs to the right classes in different rooms, depending on how many people will be taking that class in that room, so that the instructors know which laptops to take to the room with them to teach the class that day.
For example, I have the raw data:
Date Room ClassName HeadCount
---- ---- --------- ---------
11/30 101 Intro 10
11/30 102 Intro 15
11/30 103 Course 2 5
12/1 101 Intro 10
12/1 102 Course 2 15
12/1 103 Course 3 10
I also know the following about the laptops:
ClassName LaptopID
--------- ---------
Intro LT.Intro_1
Intro ...
Intro LT.Intro_30
Course 2 LT.Course 2_1
Course 2 ...
Course 2 LT.Course 2_30
Course 3 LT.Course 3_1
Course 3 ...
Course 3 LT.Course 3_30
Based on the above two tables, I would want to output:
Date Room ClassName HeadCount First Laptop Last Laptop
---- ---- --------- --------- ------------ -----------
11/30 101 Intro 10 LT.Intro_1 LT.Intro_10
11/30 102 Intro 15 LT.Intro_11 LT.Intro_25
11/30 103 Course 2 5 LT.Course 2_1 LT.Course 2_5
12/1 101 Intro 10 LT.Intro_1 LT.Intro_10
12/1 102 Course 2 15 LT.Course 2_1 LT.Course 2_15
12/1 103 Course 3 10 LT.Course 3_1 LT.Course 3_10
I know this is a windowing function, but MS Access doesn't have lead or lag. Is there a workaround?
You might want to change your table definitions for better performance. I have recreated two tables as you've mentioned.
You know your laptop ids are in sequence and you know the headcount per class. In order to follow a lead, you must know the last headcount.
which would be toal attendees on the same date, for the same class, before current class/event.
x = sum(headCount) where id < currentID & classname = currentClassname & date = currentDate. (Current means currentRow.)
Now you know total laptops used before the current row and the headCount for current row. The First laptop would be
f = min(laptopid) where laptopid > x (x being totaLaptopUsedBefore this Row)
for the Last laptop, you must also add the current headcount.
l = min(laptopid) where laptopid >= currentHeadCount + x
Note f checks laptopid is greater and L checks >=.
Here is a working demo which you can improve on:
Table1: tbl_ClassEvents
+----+------------+------+-----------+-----------+
| ID | date | Room | ClassName | HeadCount |
+----+------------+------+-----------+-----------+
| 1 | 30/11/2017 | 101 | Intro | 10 |
| 2 | 30/11/2017 | 102 | intro | 15 |
| 3 | 30/11/2017 | 103 | Course 2 | 5 |
| 4 | 01/12/2017 | 101 | Intro | 10 |
| 5 | 01/12/2017 | 102 | Course 2 | 15 |
| 6 | 01/12/2017 | 103 | Course 3 | 10 |
| 7 | 17/11/2017 | 101 | Intro | 16 |
+----+------------+------+-----------+-----------+
Table2: Tbl_ClassVsLaptop
+----+-----------+----------------+
| Id | ClassName | LaptopId |
+----+-----------+----------------+
| 1 | Intro | LT.Intro_1 |
| 2 | Intro | LT.Intro_2 |
| 3 | Intro | LT.Intro_3 |
| 4 | Intro | LT.Intro_4 |
| 5 | Intro | LT.Intro_5 |
| 6 | Intro | LT.Intro_6 |
| 7 | Intro | LT.Intro_7 |
| 8 | Intro | LT.Intro_8 |
| 9 | Intro | LT.Intro_9 |
| 10 | Intro | LT.Intro_10 |
| 11 | Intro | LT.Intro_11 |
| 12 | Intro | LT.Intro_12 |
| 13 | Intro | LT.Intro_13 |
| 14 | Intro | LT.Intro_14 |
| 15 | Intro | LT.Intro_15 |
| 16 | Intro | LT.Intro_16 |
| 17 | Intro | LT.Intro_17 |
| 18 | Intro | LT.Intro_18 |
| 19 | Intro | LT.Intro_19 |
| 20 | Intro | LT.Intro_20 |
| 21 | Intro | LT.Intro_21 |
| 22 | Intro | LT.Intro_22 |
| 23 | Intro | LT.Intro_23 |
| 24 | Intro | LT.Intro_24 |
| 25 | Intro | LT.Intro_25 |
| 26 | Intro | LT.Intro_26 |
| 27 | Intro | LT.Intro_27 |
| 28 | Intro | LT.Intro_28 |
| 29 | Intro | LT.Intro_29 |
| 30 | Intro | LT.Intro_30 |
| 31 | Course 2 | LT.Course 2_1 |
| 32 | Course 2 | LT.Course 2_2 |
| 33 | Course 2 | LT.Course 2_3 |
| 34 | Course 2 | LT.Course 2_4 |
| 35 | Course 2 | LT.Course 2_5 |
| 36 | Course 2 | LT.Course 2_6 |
| 37 | Course 2 | LT.Course 2_7 |
| 38 | Course 2 | LT.Course 2_8 |
| 39 | Course 2 | LT.Course 2_9 |
| 40 | Course 2 | LT.Course 2_10 |
| 41 | Course 2 | LT.Course 2_11 |
| 42 | Course 2 | LT.Course 2_12 |
| 43 | Course 2 | LT.Course 2_13 |
| 44 | Course 2 | LT.Course 2_14 |
| 45 | Course 2 | LT.Course 2_15 |
| 46 | Course 2 | LT.Course 2_16 |
| 47 | Course 2 | LT.Course 2_17 |
| 48 | Course 2 | LT.Course 2_18 |
| 49 | Course 2 | LT.Course 2_19 |
| 50 | Course 2 | LT.Course 2_20 |
| 51 | Course 2 | LT.Course 2_21 |
| 52 | Course 2 | LT.Course 2_22 |
| 53 | Course 2 | LT.Course 2_23 |
| 54 | Course 2 | LT.Course 2_24 |
| 55 | Course 2 | LT.Course 2_25 |
| 56 | Course 2 | LT.Course 2_26 |
| 57 | Course 2 | LT.Course 2_27 |
| 58 | Course 2 | LT.Course 2_28 |
| 59 | Course 2 | LT.Course 2_29 |
| 60 | Course 2 | LT.Course 2_30 |
| 61 | Course 3 | LT.Course 3_1 |
| 62 | Course 3 | LT.Course 3_2 |
| 63 | Course 3 | LT.Course 3_3 |
| 64 | Course 3 | LT.Course 3_4 |
| 65 | Course 3 | LT.Course 3_5 |
| 66 | Course 3 | LT.Course 3_6 |
| 67 | Course 3 | LT.Course 3_7 |
| 68 | Course 3 | LT.Course 3_8 |
| 69 | Course 3 | LT.Course 3_9 |
| 70 | Course 3 | LT.Course 3_10 |
| 71 | Course 3 | LT.Course 3_11 |
| 72 | Course 3 | LT.Course 3_12 |
| 73 | Course 3 | LT.Course 3_13 |
| 74 | Course 3 | LT.Course 3_14 |
| 75 | Course 3 | LT.Course 3_15 |
| 76 | Course 3 | LT.Course 3_16 |
| 77 | Course 3 | LT.Course 3_17 |
| 78 | Course 3 | LT.Course 3_18 |
| 79 | Course 3 | LT.Course 3_19 |
| 80 | Course 3 | LT.Course 3_20 |
| 81 | Course 3 | LT.Course 3_21 |
| 82 | Course 3 | LT.Course 3_22 |
| 83 | Course 3 | LT.Course 3_23 |
| 84 | Course 3 | LT.Course 3_24 |
| 85 | Course 3 | LT.Course 3_25 |
| 86 | Course 3 | LT.Course 3_26 |
| 87 | Course 3 | LT.Course 3_27 |
| 88 | Course 3 | LT.Course 3_28 |
| 89 | Course 3 | LT.Course 3_29 |
| 90 | Course 3 | LT.Course 3_30 |
+----+-----------+----------------+
Here is the query:
SELECT tbl_classEvents.ID
,tbl_classEvents.DATE
,tbl_classEvents.Room
,tbl_classEvents.ClassName
,tbl_classEvents.HeadCount
,(
SELECT min(laptopId)
FROM tbl_ClassVsLaptop T1
WHERE T1.ClassName = tbl_ClassEvents.ClassNAme
AND Mid([T1.LaptopID], InStrRev([T1.LaptopID], "_") + 1, 3) > (
+ Nz((
SELECT sum(headCount)
FROM tbl_classEvents T2
WHERE T2.ID < Tbl_ClassEvents.ID
AND T2.[DATE] = [Tbl_ClassEvents].[DATE]
AND T2.[ClassName] = [Tbl_ClassEvents].[ClassName]
), 0)
)
) AS FirstLaptop
,(
SELECT min(laptopId)
FROM tbl_ClassVsLaptop T1
WHERE T1.ClassName = tbl_ClassEvents.ClassNAme
AND Mid([T1.LaptopID], InStrRev([T1.LaptopID], "_") + 1, 3) >= (
+ [tbl_classEvents].[HeadCount] + Nz((
SELECT sum(headCount)
FROM tbl_classEvents T2
WHERE T2.ID < Tbl_ClassEvents.ID
AND T2.[DATE] = [Tbl_ClassEvents].[DATE]
AND T2.[ClassName] = [Tbl_ClassEvents].[ClassName]
), 0)
)
) AS LastLaptop
FROM tbl_classEvents
ORDER BY tbl_classEvents.DATE
,tbl_classEvents.Room
,tbl_classEvents.ClassNAme;
And the output:
+----+------------+------+-----------+-----------+---------------+----------------+
| ID | DATE | Room | ClassName | HeadCount | FirstLaptop | LastLaptop |
+----+------------+------+-----------+-----------+---------------+----------------+
| 7 | 17/11/2017 | 101 | Intro | 16 | LT.Intro_1 | LT.Intro_16 |
| 1 | 30/11/2017 | 101 | Intro | 10 | LT.Intro_1 | LT.Intro_10 |
| 2 | 30/11/2017 | 102 | intro | 15 | LT.Intro_11 | LT.Intro_25 |
| 3 | 30/11/2017 | 103 | Course 2 | 5 | LT.Course 2_1 | LT.Course 2_5 |
| 4 | 01/12/2017 | 101 | Intro | 10 | LT.Intro_1 | LT.Intro_10 |
| 5 | 01/12/2017 | 102 | Course 2 | 15 | LT.Course 2_1 | LT.Course 2_15 |
| 6 | 01/12/2017 | 103 | Course 3 | 10 | LT.Course 3_1 | LT.Course 3_10 |
+----+------------+------+-----------+-----------+---------------+----------------+

Creating a SSRS report from 2 Tables

I Have two tables in a sql server database.
Here's my First table,Table1
+------------+------------------+----------------+
| Project ID | Project Manager | Approved Hours |
+------------+------------------+----------------+
| 1 | Mr.A | 120 |
| 2 | Mr.B | 100 |
+------------+------------------+----------------+
Here's my Second Table,Table 2
+-----------+-----------------+-----------+----------+---------------+
| ProjectID | Project Manager | Personnel | Week No. | Working Hours |
+-----------+-----------------+-----------+----------+---------------+
| 1 | Mr.A | Tom | 1 | 20 |
| 1 | Mr.A | Tom | 2 | 20 |
| 1 | Mr.A | Tom | 3 | 10 |
| 1 | Mr.A | Harry | 1 | 20 |
| 1 | Mr.A | Harry | 2 | 20 |
| 1 | Mr.A | Harry | 3 | 20 |
| 2 | Mr.B | Tom | 1 | 20 |
| 2 | Mr.B | Tom | 2 | 10 |
| 2 | Mr.B | Tom | 3 | 20 |
| 2 | Mr.B | Harry | 1 | 20 |
| 2 | Mr.B | Harry | 2 | 15 |
+-----------+-----------------+-----------+----------+---------------+
I would like to create a ssrs report that looks like this.I'm using the 2012 version.
Actual Hours being the sum of working Hours for each Project.
+------------+-----------------+----------------+--------------+
| Project ID | Project Manager | Approved Hours | Actual Hours |
+------------+-----------------+----------------+--------------+
| 1 | Mr.A | 120 | 110 |
| 2 | Mr.B | 100 | 85 |
+------------+-----------------+----------------+--------------+
I'm kind of new to SQL, Can I get this done with a single query.
As #jarlh Suggest simply do INNER JOIN & group by as below :
SELECT T.[Project ID],
T.[Project Manager],
T.[Approved Hours],
SUM(T1.[Working Hours]) [Actual Hours]
FROM Table1 T
INNER JOIN Table2 T1 ON T.[Project ID] = T1.[Project ID]
GROUP BY T.[Project ID],
T.[Project Manager],
T.[Approved Hours];
Result :
+------------+-----------------+----------------+--------------+
| Project ID | Project Manager | Approved Hours | Actual Hours |
+------------+-----------------+----------------+--------------+
| 1 | Mr.A | 120 | 110 |
| 2 | Mr.B | 100 | 85 |
+------------+-----------------+----------------+--------------+

SQL only select rows with max date within each user

SQL beginner here. I've got a simple test that users take, and each row is the answer to one of their questions. They're allowed to take the exam once per day, so some people take it a second time on another day, and thus will have many rows with different test dates. What I'm basically trying to do is get each user's most recent score.
Here is what my data looks like (table name is dumdum):
+----------+----------------+----------+------------------+
| USERNAME | CORRECT_ANSWER | RESPONSE | DATE_TAKEN |
+----------+----------------+----------+------------------+
| matt | 1 | 1 | 3/23/15 1:04:26 |
| matt | 2 | 2 | 3/23/15 1:04:28 |
| matt | 3 | 3 | 3/23/15 1:04:23 |
| david | 1 | 3 | 3/20/15 1:04:25 |
| david | 2 | 2 | 3/20/15 1:04:28 |
| david | 3 | 1 | 3/20/15 1:04:30 |
| david | 1 | 1 | 3/21/15 11:03:14 |
| david | 2 | 3 | 3/21/15 11:03:17 |
| david | 3 | 2 | 3/21/15 11:03:19 |
| chris | 1 | 2 | 3/17/15 12:45:52 |
| chris | 2 | 2 | 3/17/15 12:45:56 |
| chris | 3 | 3 | 3/17/15 12:45:59 |
| peter | 1 | 1 | 3/19/15 2:45:33 |
| peter | 2 | 3 | 3/19/15 2:45:35 |
| peter | 3 | 2 | 3/19/15 2:45:38 |
| peter | 1 | 1 | 3/20/15 12:32:04 |
| peter | 2 | 2 | 3/20/15 12:32:05 |
| peter | 3 | 3 | 3/20/15 12:32:05 |
+----------+----------------+----------+------------------+
and what I'm trying to get in the end...
+----------+------------------+-------+
| USERNAME | MOST_RECENT_TEST | SCORE |
+----------+------------------+-------+
| matt | 3/23/2015 | 100 |
| david | 3/21/2015 | 33 |
| chris | 3/17/2015 | 67 |
| peter | 3/20/2015 | 100 |
+----------+------------------+-------+
I ran into some trouble because I need to go by day, and not by day/time, so I had to do a weird maneuver where I went to character and back to date... This is what I have so far, but I can't figure out how to use only the scores from the most recent test (right now it's factoring in all scores from every test ever taken)...
SELECT username, to_date(substr(max(test_date),1,9),'dd-MON-yy') as most_recent_test, round((sum(case when response=correct_answer then 1 end)/3)*100,0) as score
FROM dumdum group by username
Any help would be appreciated! Thanks!
There are several solutions to this problem this one uses the WITH clause and the RANK function.
It also uses the TRUNC function rather than to_date(substr(
with mxDate as
(SELECT USERNAME,
TRUNC(DATE_TAKEN) as MOST_RECENT_TEST,
CASE WHEN CORRECT_ANSWER = RESPONSE THEN 1 else 0 END as SCORE,
RANK () OVER (PARTITION BY USERNAME
ORDER BY TRUNC(DATE_TAKEN) DESC) Rk
FROM dumdum)
SELECT
USERNAME,
MOST_RECENT_TEST,
SUM(SCORE)/3 * 100
FROM
mxDate
WHERE
rk = 1
GROUP BY
USERNAME,
MOST_RECENT_TEST
Demo

SQL Query - Grouping Data

So every morning at work we have a stand-up meeting. We throw the nearest object to hand around the room as a method of deciding who speaks in what order. Being slightly odd I decided it could be fun to get some data on these throws. So, every morning I memorise the order of throws (as well as other relevant things like who dropped the ball/strange sponge object that was probably once a ball too and who threw to someone who'd already been or just gave an atrocious throw), and record this data in a table:
+---------+-----+------------+----------+---------+----------+--------+--------------+
| throwid | day | date | thrownum | thrower | receiver | caught | correctthrow |
+---------+-----+------------+----------+---------+----------+--------+--------------+
| 1 | 1 | 10/01/2012 | 1 | dan | steve | 1 | 1 |
| 2 | 1 | 10/01/2012 | 2 | steve | alice | 1 | 1 |
| 3 | 1 | 10/01/2012 | 3 | alice | matt | 1 | 1 |
| 4 | 1 | 10/01/2012 | 4 | matt | justin | 1 | 1 |
| 5 | 1 | 10/01/2012 | 5 | justin | arif | 1 | 1 |
| 6 | 1 | 10/01/2012 | 6 | arif | pete | 1 | 1 |
| 7 | 1 | 10/01/2012 | 7 | pete | greg | 0 | 1 |
| 8 | 1 | 10/01/2012 | 8 | greg | alan | 1 | 1 |
| 9 | 1 | 10/01/2012 | 9 | alan | david | 1 | 1 |
| 10 | 1 | 10/01/2012 | 10 | david | dan | 1 | 1 |
| 11 | 2 | 11/01/2012 | 1 | dan | david | 1 | 1 |
| 12 | 2 | 11/01/2012 | 2 | david | alice | 1 | 1 |
| 13 | 2 | 11/01/2012 | 3 | alice | steve | 1 | 1 |
| 14 | 2 | 11/01/2012 | 4 | steve | arif | 1 | 1 |
| 15 | 2 | 11/01/2012 | 5 | arif | pete | 0 | 1 |
| 16 | 2 | 11/01/2012 | 6 | pete | justin | 1 | 1 |
| 17 | 2 | 11/01/2012 | 7 | justin | alan | 1 | 1 |
| 18 | 2 | 11/01/2012 | 8 | alan | dan | 1 | 1 |
| 19 | 2 | 11/01/2012 | 9 | dan | greg | 1 | 1 |
+---------+-----+------------+----------+---------+----------+--------+--------------+
I've now got quite a few days worth of data for this, and I'm starting to run some queries on it for my own purposes (I've not told the rest of the team yet...wouldn't like to influence the results). I've done a few with no issues, but I'm stuck trying to get a certain result out.
What I'm looking for is the number of times each person has been the last team member to receive the ball. Now, as you can see on the table, due to absences etc the number of throws per day is not always constant, so I can't simply select the receiver by thrownum.
In the case for the data above, it would return:
+--------+-------------------+
| person | LastReceiverTotal |
+--------+-------------------+
| dan | 1 |
| greg | 1 |
+--------+-------------------+
I've got this far:
SELECT MAX(thrownum) AS LastThrowNum, day FROM Throws GROUP BY day
Now, this returns some useful data. I get the highest thrownum for each and every day. It would seem like all I need to do is get the receiver for this value, and then get a count grouped by receiver to get my answer. This doesn't work, though, because the resultset isn't what it seems due to the above query using aggregate functions.
I suspect there's a much better way of designing tables to store the data to be honest, but equally I'm also sure there's a way to get this information with the tables as they are - some kind of inner query? I can't figure out how it would work. Can anyone shed some light on how this would be done?
The query that you have gives you the biggest thrownum for each day.
With that, you just do a inner join with your table and get the receiver and the number of times he happears.
select t.receiver as person, count(t.day) as LastReceiverTotal from Throws t
inner join (SELECT MAX(thrownum) AS LastThrowNum, day FROM Throws GROUP BY day) a on a.LastThrowNum = t.thrownum and a.day = t.day
group by t.receiver