How to use microsoft access or sql pivot - sql

I would like to use microsoft access or query to change from table1
student name course_attended date quiz score
john course 1 3/1/2017 98
carl course 1 3/1/2017 90
george course 1 3/1/2017 77
john course 2 3/5/2017 99
carl course 2 3/5/2017 96
george course 2 3/5/2017 80
john course 3 4/4/2017 77
carl course 3 4/4/2017 80
george course 3 4/4/2017 85
to table2
student name course 1 course 2 course 3
john 3/1/2017 3/5/2017 4/4/2017
98 99 95
carl 3/1/2017 3/5/2017 4/4/2017
90 96 89
george 3/1/2017 3/5/2017 4/4/2017
77 80 85
Basically, with select distinct [student name] use transformation and pivot
to change from table1 to table2. Please help. I would be greatly appreciated it.

If you don't need to do any calcs on the output, try:
TRANSFORM First([attend_date] & Chr(13) & Chr(10) & [quiz_score]) AS Data
SELECT student_name
FROM Tablename
GROUP BY student_name
PIVOT course;
Date is a reserved word. Should not use reserved words as names. Also, avoid spaces and special characters/punctuation (underscore only exception) in names.

I tried this,
TRANSFORM First([date_a] & Chr(13) & Chr(10) & [quiz_score]) AS Data
SELECT student_name
FROM tbl_quiz
GROUP BY student_name
PIVOT course_attended;
and the query does not show the quiz_score. However, the form created from the query result shows it.
Thanks a lot.

Related

How can I group and get MS Access query to show only rows with a maximum value in a specified field for a consecutive number of times?

I have a large access table that I need to pull specific data from with a query.
I need to get a list of all the IDs that meet a specific criteria, i.e. 3 months in a row with a cage number less than 50.
The SQL code I'm currently working with is below, but it only gives me which months of the past 3 had a cage number below 50.
SELECT [AbBehWeeklyMonitor Database].AnimalID, [AbBehWeeklyMonitor Database].Date, [AbBehWeeklyMonitor Database].Cage
FROM [AbBehWeeklyMonitor Database]
WHERE ((([AbBehWeeklyMonitor Database].Date)>=DateAdd("m",-3,Date())) AND (([AbBehWeeklyMonitor Database].Cage)<50))
ORDER BY [AbBehWeeklyMonitor Database].AnimalID DESC;
I would need it to look at the past 3 months for each ID, and only output if all 3 met the specific criteria, but I'm not sure where to go from here.
Any help would be appreciated.
Data Sample:
Date
AnimalID
Cage
6/28/2022
12345
50
5/19/2021
12345
32
3/20/2008
12345
75
5/20/2022
23569
4
8/20/2022
23569
4
5/20/2022
44444
71
8/1/2012
44444
4
4/1/2022
78986
30
1/20/2022
78986
1
9/14/2022
65659
59
8/10/2022
65659
48
7/14/2022
65659
30
6/14/2022
95659
12
8/14/2022
91111
51
7/14/2022
91111
5
6/14/2022
91111
90
8/14/2022
88888
4
7/14/2022
88888
5
6/14/2022
88888
15
Consider:
Query1:
SELECT AnimalID, Count(*) AS Cnt
FROM Table1
WHERE (((Cage)<50) AND (([Date]) Between #6/1/2022# And #8/31/2022#))
GROUP BY AnimalID
HAVING (((Count(*))=3));
Query2
SELECT Table1.*
FROM Query1 INNER JOIN Table1 ON Query1.AnimalID = Table1.AnimalID
WHERE ((([Date]) Between #6/1/2022# And #8/31/2022#));
Output:
Date AnimalID Cage
6/14/2022 65659 12
7/14/2022 65659 30
8/10/2022 65659 48
6/14/2022 88888 15
7/14/2022 88888 5
8/14/2022 88888 4
Date is a reserved word and really should not use reserved words as names.

Avoid duplicates in col values

I have a sp result like,
subject | Chapter no. | marks
English 1 99
English 2 99
English 3 99
Science 1 100
Science 2 100
This sp result is based on subject, each subject may have different chapterno. but the marks are based on the subject. So I have to avoid the duplication to avoid error while calculating the total marks.
Hence I need this like,
subject | Chapter no. | marks
English 1 99
English 2 0/null
English 3 0/null
Science 1 100
Science 2 0/null
Please guide me to solve this.
You can try like this:
SELECT MIN([Chapter no.]) AS col, subject
FROM yourTable
GROUP BY subject

Order By Sums, while not grouping like rows

Suppose I have data that looks like this as the result of a query
SKU | STOCK | SNACK | FLAVOR
1234 45 Chips BBQ
1236 87 Chips BBQ
2345 12 Pretzel Bacon
3456 51 Chips Ranch
4567 32 Pretzel Classic
5678 142 Candy Chocolate
... ... ... ...
Is it possible to have SQL in an ORDER BY line that allows me to display the above data first sorted by whatever Snack (Chips, Pretzel, Candy, etc.) has the largest SUM(Stock) and then by Stock DESC while not merging any of the entries? I briefly tried to use a line similar to
ORDER BY
SUM(Snack) DESC,
SUM(Flavor) DESC,
Stock DESC
but could not determine how the GROUP BY statement should be laid out.
You can use DSum to compute total STOCK for each SNACK without a GROUP BY. And use that Dsum in the ORDER BY. I also needed to use Val() on the DSum values to make it sort correctly.
SELECT y.SKU, y.STOCK, y.SNACK, y.FLAVOR
FROM YourTable AS y
ORDER BY
Val(DSum("[STOCK]", "YourTable", "[SNACK]='" & y.SNACK & "'")) DESC,
y.STOCK DESC;
Be aware that DSum is Access-specific so this is not suitable if you want a query which can be ported to another database.
Try with following SQL
select sku, stock, data.snack, flavor, summ = summ.summ
from data
join (select snack, summ = sum(stock) from data group by snack) as summ
on summ.snack = data.snack
order by summ desc, stock desc
SKU|STOCK|SNACK|FLAVOR|SUMM
1236 87 Chips BBQ 183
3456 51 Chips Ranch 183
1234 45 Chips BBQ 183
5678 142 Candy Chocolate 142
4567 32 Pretzel Classic 44
2345 12 Pretzel Bacon 44

SQL Select Distinct returning duplicates

I am trying to return the country, golfer name, golfer age, and average drive for the golfers with the highest average drive from each country.
However I am getting a result set with duplicates of the same country. What am I doing wrong? here is my code:
select distinct country, name, age, avgdrive
from pga.golfers S1
inner join
(select max(avgdrive) as MaxDrive
from pga.golfers
group by country) S2
on S1.avgdrive = s2.MaxDrive
order by avgdrive;
These are some of the results I've been getting back, I should only be getting 15 rows, but instead I'm getting 20:
COUN NAME AGE AVGDRIVE
---- ------------------------------ ---------- ----------
Can Mike Weir 35 279.9
T&T Stephen Ames 41 285.8
USA Tim Petrovic 39 285.8
Ger Bernhard Langer 47 289.3
Swe Fredrik Jacobson 30 290
Jpn Ryuji Imada 28 290
Kor K.J. Choi 37 290.4
Eng Greg Owen 33 291.8
Ire Padraig Harrington 33 291.8
USA Scott McCarron 40 291.8
Eng Justin Rose 25 293.1
Ind Arjun Atwal 32 293.7
USA John Rollins 30 293.7
NIr Darren Clarke 37 294
Swe Daniel Chopra 31 297.2
Aus Adam Scott 25 300.6
Fij Vijay Singh 42 300.7
Spn Sergio Garcia 25 301.9
SAf Ernie Els 35 302.9
USA Tiger Woods 29 315.2
You are missing a join condition:
select s1.country, s1.name, s1.age, s1.avgdrive
from pga.golfers S1 inner join
(select country, max(avgdrive) as MaxDrive
from pga.golfers
group by country
) S2
on S1.avgdrive = s2.MaxDrive and s1.country = s2.country
order by s1.avgdrive;
Your problem is that some people in one country have the same average as the best in another country.
DISTINCT eliminated duplicate rows, not values in some fields.
To get a list of countries with ages, names, and max drives, you would need to group the whole select by country.

Access SQL - Select only the last sequence

I have a table with an ID and multiple informative columns. Sometimes however, I can have multiple data for an ID, so I added a column called "Sequence". Here is a shortened example:
ID Sequence Name Tel Date Amount
124 1 Bob 873-4356 2001-02-03 10
124 2 Bob 873-4356 2002-03-12 7
124 3 Bob 873-4351 2006-07-08 24
125 1 John 983-4568 2007-02-01 3
125 2 John 983-4568 2008-02-08 13
126 1 Eric 345-9845 2010-01-01 18
So, I would like to obtain only these lines:
124 3 Bob 873-4351 2006-07-08 24
125 2 John 983-4568 2008-02-08 13
126 1 Eric 345-9845 2010-01-01 18
Anyone could give me a hand on how I could build a SQL query to do this ?
Thanks !
You can calculate the maximum sequence using group by. Then you can use join to get only the maximum in the original data.
Assuming your table is called t:
select t.*
from t join
(select id, MAX(sequence) as maxs
from t
group by id
) tmax
on t.id = tmax.id and
t.sequence = tmax.maxs