Create Access crosstab from query with variable number of columns and multiple values - ms-access

I have a query made by joining data from three tables in a MS-Access DB
simsID Forename Surname Class AssessmentName Mark Percentage
1234 Joe Bloggs 13X Test1 20 50
1235 Fred Bloggs 13Y Test1 31 77.5
1234 Joe Bloggs 13X Test2 30 60
1235 Fred Bloggs 13Y Test2 10 20
1235 Fred Bloggs 13Y Test3 20 33.3333333333333
1234 Joe Bloggs 13X Test3 34 56.6666666666667
I would like to display the data as follows
ID Forename Surname Class Test1 Mark Test1 % Test2 Mark Test2 % Test3 Mark Test3 %
1234 Joe Bloggs 13X 20 50 30 60 34 56.6666666666667
1235 Fred Bloggs 13Y 31 77.5 10 20 20 33.3333333333333
The only way I can see is to do two crosstab queries and then join them.
AllStudentData_Marks query
TRANSFORM Avg(AllStudentData.Mark) AS AvgOfMark
SELECT AllStudentData.simsID AS ID, AllStudentData.Forename AS Forename, AllStudentData.Surname AS Surname, AllStudentData.Class AS Class
FROM AllStudentData
GROUP BY AllStudentData.simsID, AllStudentData.Forename, AllStudentData.Surname, AllStudentData.Class
PIVOT AllStudentData.Assessments.AssessmentName & " Mark";
AllStudentData_Precentage query
TRANSFORM Avg(AllStudentData.Percentage) AS AvgOfPercentage
SELECT AllStudentData.simsID AS ID, AllStudentData.Forename AS Forename, AllStudentData.Surname AS Surname, AllStudentData.Class AS Class
FROM AllStudentData
GROUP BY AllStudentData.simsID, AllStudentData.Forename, AllStudentData.Surname, AllStudentData.Class
PIVOT AllStudentData.Assessments.AssessmentName & " %";
Join query
SELECT AllStudentData_Marks.*, AllStudentData_Percentage.*
FROM AllStudentData_Marks INNER JOIN AllStudentData_Percentage ON AllStudentData_Marks.ID = AllStudentData_Percentage.ID;
As expected this gives me a big table:
AllStudentData_Marks.ID AllStudentData_Marks.Forename AllStudentData_Marks.Surname AllStudentData_Marks.Class Test1 Mark Test2 Mark Test3 Mark AllStudentData_Percentage.ID AllStudentData_Percentage.Forename AllStudentData_Percentage.Surname AllStudentData_Percentage.Class Test1 % Test2 % Test3 %
1234 Joe Bloggs 13X 20 30 34 1234 Joe Bloggs 13X 50 60 56.6666666666667
1235 Fred Bloggs 13Y 31 10 20 1235 Fred Bloggs 13Y 77.5 20 33.3333333333333
I would like to limit the amount of columns (ie not repeat the names) and have more sensible column names (Forename, Surname, etc), but the number of assessment columns is not fixed hence why I am using the wildcard in SELECT.
How can I limit this final query to just return my compact table with sensible headings? ie
ID Forename Surname Class Test1 Mark Test1 % Test2 Mark Test2 % Test3 Mark Test3 %
1234 Joe Bloggs 13X 20 50 30 60 34 56.6666666666667
1235 Fred Bloggs 13Y 31 77.5 10 20 20 33.3333333333333
Thanks in advance for reading.

Yes, two joined CROSSTABS is one way to pivot two sets of values. Another method described in http://allenbrowne.com/ser-67.html#MultipleValues.
And yet another approach involves a UNION query which is then used as source for CROSSTAB. Working with the sample dataset you posted, consider:
Query1:
SELECT simsID, Forename, Surname, Class, AssessmentName, Mark AS Data, "M" AS Cat FROM dataset
UNION SELECT simsID, Forename, Surname, Class, AssessmentName, Percentage, "P" AS Cat FROM dataset;
Query2:
TRANSFORM Sum(Query1.Data) AS SumOfData
SELECT Query1.simsID, Query1.Surname, Query1.Class
FROM Query1
GROUP BY Query1.simsID, Query1.Forename, Query1.Surname, Query1.Class
PIVOT [AssessmentName] & [Cat];
Might find this of interest Crosstab Query on multiple data points

Related

Altering A table to add an extra column (rank) with a Mysql DENSE_RANK() function from some details (id, subject, points)

id subject points Rank
joe maths 70 1
Mike maths 60 2
Sarah maths 40 3
mike English 80 1
Sarah English 65 2
joe English 55 3
Sarah Chemistry 80 1
Mike Chemistry 60 2
joe Chemistry 43 3
I was able to query this in mysql but i want to store the rank column in the table (grades) using the ALTER command
i tried
ALTER TABLE grades
ADD COLUMN Rank
GENERATE ALWAYS AS
DENSE_RANK() OVER(PARTITION BY subjects ORDER BY points DESC)
ORDER BY id,
Rank
but did not work
Hope i could find some help out there

I am trying to return combined rows in the same table based on a key in a second table

I probably haven't explained this very well in the title but I have two tables. Here is a simple version.
channel_data
entry_id channel_id first_name last_name model other_fields
1 4 John Smith
2 4 Jane Doe
3 4 Bill Evans
4 15 235
5 15 765
6 15 543
7 15 723
8 15 354
9 15 976
10 1 xxx
11 2 yyy
12 3 123
channel_titles
entry_id author_id channel_id
1 101 4
2 102 4
3 103 4
4 101 15
5 101 15
6 101 15
7 102 15
8 102 15
9 103 15
10 101 1
11 102 2
12 103 3
I am not able to re-model the data unfortunately.
I need to list all the rows with a channel_id 15 from channel_data and beside them the first_name and last_name which has the same author_id from channel_titles.
What I want to return is this:
Model First Name Last Name
---------------------------------
235 John Smith
765 John Smith
543 John Smith
723 Jane Doe
354 Jane Doe
976 Bill Evans
If Model was in one table and Names were in another this would be much simpler but I'm not sure how to go about this when they are in the same table.
========================================
Edited to clarify.
I need to get each model with a channel_id 15 from channel_data
For each model I need to look up the entry_id in channel_titles to find the author_id
I need to find the row with that author_id AND channel_id 4 in channel titles (each row with channel_id 4 has a unique author_id).
I need to take the entry_id of this row back to channel_data and get the first_name and last_name to go with the model.
I am well aware that the data is not structured well but that is what I have to work with. I am trying to accomplish a very small task in a much larger system, remodelling the data is not an option at this point.
I think sub-queries might be what I am looking for but this is not my area at all usually.
Ok, that is convoluted. However, based on your description, this query should give you the results you want. The WHERE and JOIN descriptions follow the logic you have described in your question.
SELECT cd1.model, cd2.first_name, cd2.last_name
FROM channel_data cd1
JOIN channel_titles ct1 ON ct1.entry_id = cd1.entry_id
JOIN channel_titles ct2 ON ct2.channel_id = 4 AND ct2.author_id = ct1.author_id
JOIN channel_data cd2 ON cd2.entry_id = ct2.entry_id
WHERE cd1.channel_id = 15
ORDER BY cd1.entry_id
Output:
model first_name last_name
235 John Smith
765 John Smith
543 John Smith
723 Jane Doe
354 Jane Doe
976 Bill Evans
Demo on SQLFiddle

Multi-event tournament standings

I am trying to grab a participants rankings in a multi-event tournament.
I can do a ranking for a single event pretty easily. Is there a way to find ALL in one go?
Given input: "Bob"
Data example: Desired output:
Name | Event | Score Name | Event | Score | Rank
-------------------- ----------------------------
Bob 1 100 Bob 1 100 1
Bob 2 75 Bob 2 75 3
Bob 3 80 Bob 3 80 2
Jill 2 90
Jill 3 60
Chris 1 70
Chris 2 50
Chris 3 100
Amy 1 85
Amy 2 95
Amy 3 65
The catch: I do not have access to the Rank()
function with my version of SQL, and updating is not possible in this scenario.
Clearly I could just do the score per event separately in a loop,
but I'd like to try to do it all in one go.
You can emulate a ranking function in MySQL using a self-join to values with a higher score in the same Event, and then counting the number of higher scores for each participant:
SELECT s1.Name, s1.Event, s1.Score, COUNT(s2.Name)+1 AS Rank
FROM scores s1
LEFT JOIN scores s2 ON s2.Event = s1.Event AND s2.Score > s1.Score
WHERE s1.Name = 'Bob'
GROUP BY s1.Name, s1.Event, s1.Score
ORDER BY s1.Name, s1.Event
Output:
Name Event Score Rank
Bob 1 100 1
Bob 2 75 3
Bob 3 80 2
Demo on dbfiddle

Pivot combo box table in ms access

I am using this SQL:
TRANSFORM Max(table1.[quiz]) AS MaxOfquiz
SELECT table1.[quizdate], table1.[studentname], Max(table1.[quiz]) AS [Total Of
quizscores]
FROM table1
GROUP BY table1.[quizdate], table1.[studentname]
PIVOT table1.[coursename];
To try and pivot a combobox table:
Table1
ID quizdate coursename studentname quiz
1 02-Jan-21 math john 100
2 03-Feb-21 science joe 99
3 04-Mar-21 physics monica 97
4 05-Apr-20 language mike 88
Where coursename is a dropdown (math, science, physics, language) into
Table 2
studentname math science physics language
john 100
joe 99
monica 97
mike 88
I got these results:
quizdate studentname Total Of quizscores 1 2 3 4
4/4/2016 moe 88 88
1/1/2017 john 100 100
2/2/2017 joe 99 99
3/3/2017 monica 97 97
It seems that combox box coursename can't be pivoted as column name, but the
numbers instead. Can anyone explain how I can generate the correct results?
You answer it yourself:
Where coursename is a dropdown (math, science, physics, language)
So, in the query, the value from the field will be the ID of these "dropdowns".
To obtain coursenames, move these to a separate table and join this with Table1 in your query.

How to change record in table with consecutive value?

I have table like below :
Application_Number Id_Number1 Name
1 123 John
2 456 Alan
3 789 Charlie
4 111 Patrick
5 222 Robert
Then i would like to update record in one of rows become like this :
Application_Number Id_Number1 Name
1 123 Alias 1
2 456 Alias 2
3 789 Alias 3
4 111 Alias 4
5 222 Alias 5
if i have more than one million record do i need update syntax or any another way? I'm using SQL2008
Thanks
Select Application_Number
,Id_Number1
,'Alias' + CAST( ROW_NUMBER()
OVER (ORDER BY Application_Number) AS Varchar) AS Name
FROM Table Name