How to query sum and distinct in one sqlite query? - sqlite

I have a table with the following data:
Class Student Score Date
A Tom 10 Aug 1
B Dave 9 Aug 1
A Jan 7 Aug 2
B Jack 8 Aug 2
A Matt 5 Aug 3
B Dave 8 Aug 4
A Matt 8 Aug 4
Each student can only have one score in each day but can have multiple scores for multiple days.
I want to do a query to list total score of each class and number of student in each class. How can I do that with one query?
The expected result:
Class Student_Count Total_Score
A 3 30
B 2 25

You need to group by class, count the distinct number of students and sum the scores of all the students:
SELECT Class,
COUNT(DISTINCT Student) Student_Count,
SUM(Score) Total_Score
FROM tablename
GROUP BY Class;
See the demo.

Use a distinct student count:
SELECT Class,
COUNT(DISTINCT Student) AS Student_Count,
SUM(Score) AS Total_Score
FROM yourTable
GROUP BY
Class;

Related

Need help setting up an Access query

An example of what I'm trying to do is given below. For each person, I want a query that will look at each reason and calculate a sum of points based on: if A-F are present the points will be calculated as follows for John 10+20+30+40+50-60, i.e., A+B+C+D+E-F. If F isn't present, then it's a straight sum of the points (for Paul).
ID name points reason
1 John 10 A
2 John 20 B
3 John 30 C
4 John 40 D
5 John 50 E
6 John 60 F
7 Paul 5 A
8 Paul 10 B
9 Paul 15 C
10 Paul 20 D
11 Paul 25 E
Try this:
Select [name],
Sum(IIF([reason] = "F", -[points], [points])) As TotalPoints
From YourTable
Group By [name]
Learn more about iif here: https://support.office.com/en-us/article/iif-function-32436ecf-c629-48a3-9900-647539c764e3
There is no difference between 10+20+30+40+50-60 and what you call a straight sum.
So, all you need is to group by the name:
Select [name], Sum([points]) As TotalPoints
From YourTable
Group By [name]

last 6 months total in Teradata

I have to calculate total quantity sold for last 6 months. For example in case of January 2018 , I have to calculate told quantity sold from July - Dec 2017. This total should be grouped by primary key.
Thanks
Primary Key Date qty last 6 months quantity sold
1 1-Oct 4 0
1 1-Nov 10 4
1 5-Dec 20 14
1 1-Jan 3 34
1 1-Sep 88 0
You can calculate the range using ADD_MONTHS plus TRUNC:
WHERE datecole BETWEEN Trunc(Add_Months(Current_Date, -6), 'mon')
AND Trunc(Current_Date, 'mon') -1

Sqlite3 join tables with result

I have created 2 tables,
1 reservations (timestamp,name,phone,date,time,tableNo)
2 tables (tableId, TableNo)
Users are able to add and select entries from lists in a form
but when they reach table list i want to run a query which will check saved reservations (table1 time & tableNO) and their time is greater than a given variable, so the table2 will have to show next to table number the name and time of a saved reservation,
Hope this makes some sense:
reservations tables
name date time tableNO 1
John 20/5 12:30 5 2
Mary 20/5 15:00 2 3
4
5
What i want to achieve is:
SELECT FROM tables .... WHERE time > 13:00
reservations tables
name date time tableNO 1
John 20/5 12:30 5 2 Mary
Mary 20/5 15:00 2 3
4
5

The logic of WHERE Clause along with > operator and the sub-query

I don't get the logic for the query 3 as below, and hope someone could give me some idea.
For the query 3,
SELECT ID, NAME, AGE, SALARY FROM COMPANY WHERE AGE > (SELECT AGE FROM COMPANY WHERE SALARY < 20000);
The sub-query would find out the result where the salary < 20000 first, and that is what query2 shown as below. And then the parent query would find out the result where using all the age's record from the table COMPANY(total of 7 record: 18,19,22,23,24,29,37) to compare with the age's result from sub-query(total of 4 record: 18,19,23,29) and then show the greater record based on age.
I expect the result should only show the ID 7 only like below, since only this record is met the condition. The greater age from the result of sub-query(query 2) is 29, so only this record the age is over 29.
ID NAME AGE SALARY
7 Vicky 37 32500.0
Unfortunately my expectation is not met, and it show me the result like query 3 as below.
I hope to understand the logic how its work for query 3, and hope someone could assist.
1.sqlite> SELECT ID, NAME, AGE, SALARY FROM COMPANY;
ID NAME AGE SALARY
1 John 24 21000.0
2 Davy 22 20000.0
3 Kenny 19 9700.0
4 Henry 23 13555.0
5 Sam 18 17000.0
6 Ray 29 8000.0
7 Vicky 37 32500.0
2.sqlite> SELECT ID, NAME, AGE, SALARY FROM COMPANY WHERE SALARY < 20000;
ID NAME AGE SALARY
3 Kenny 19 9700.0
4 Henry 23 13555.0
5 Sam 18 17000.0
6 Ray 29 8000.0
3.sqlite> SELECT ID, NAME, AGE, SALARY FROM COMPANY WHERE AGE > (SELECT AGE FROM COMPANY WHERE SALARY < 20000);
ID NAME AGE SALARY
1 John 24 21000.0
2 Davy 22 20000.0
4 Henry 23 13555.0
6 Ray 29 8000.0
7 Vicky 37 32500.0
At a guess, since it doesn't throw an error (which seems a better idea; see also Col. 32's comment):
Sqlite just picks the first returned age. That age should be random, but going by the results shown in your query 2 and assuming some consistency, the first result is likely 19. Then, it picks all ages larger than 19, which is what you see in the results of query 3.
Shuffle things around or create another set of data, and see if what you get now from query 2 and 3 are consistent with this assumption.
Someone else may know the internals of Sqlite enough to explain why this happens.

SQLite - SELECT DISTINCT of one column and get the others

This has been touched on before on this website. I want distinct on group but I also want to get the other fields too. what I need is the lowest id of each group, but instead I get the highest. I've tried variod SQL queries and the nearest 2 that work are
1)
select *
from reminder
group by Eventgroup
order by autoid
2)
SELECT distinct Autoid,EventDate,Subject,birthdate,Eventgroup
from reminder
group by Eventgroup
order by autoid
Data:
EventDate Subject birthdate Eventgroup autoid
09/10/2017 Joes Birthday 09/10/1995 4 9
13/07/2017 Bill Birthday 13/07/1999 2 8
04/04/2017 Tony Birthday 04/04/1993 3 7
09/10/2016 Joes Birthday 09/10/1995 4 6
13/07/2016 Bill Birthday 13/07/1999 2 5
04/04/2016 Tony Birthday 04/04/1993 3 4
09/10/2015 Joes Birthday 09/10/1995 4 3
13/07/2015 Bill Birthday 13/07/1999 2 2
04/04/2015 Tony Birthday 04/04/1993 3 1
both of these queries return
09/10/2017 Joes Birthday 09/10/1995 4 9
13/07/2017 Bill Birthday 13/07/1999 2 8
04/04/2017 Tony Birthday 04/04/1993 3 7
what I want is the earliets dates such as
09/10/2015 Joes Birthday 09/10/1995 4 3
13/07/2015 Bill Birthday 13/07/1999 2 2
04/04/2015 Tony Birthday 04/04/1993 3 1
Join the table with a subquery that finds the earliest date for each event group.
SELECT a.*
FROM reminders a
JOIN (SELECT eventgroup, MIN(eventdate) mindate
FROM reminders
GROUP BY eventgroup) b
ON a.eventgroup = b.eventgroup AND a.eventdate = b.mindate
This is the same structure as the second query in this answer in the duplicate question.
DEMO

Resources