Counting/totaling rows in a create view statement, mysql - mysql

I have a database and I want to create a view that allows the person to invoke the view name to see the "year, semester, credits", for the view. What I want to do is have it give me the year, then the semester and then the total credits taken per semester.
So, it should return a result if I have 2 students in spring 2010, and they took 2 classes each at 3 credit hours per class at a total of 12 credits, and so on and so fourth.
EX. '2010 Spring 12'
CREATE VIEW tot_cred26
AS
SELECT DISTINCT year, semester, COUNT(credits)
FROM course INNER JOIN takes;
Thanks again guys, super new to SQL and you all have been really helpful! :)

Use GROUP BY to combine rows for each set of values. And since you want the total credits, you should use SUM; COUNT just counts the number of rows. And your INNER JOIN needs an ON clause to specify how the two tables are related; I'm assume there's a courseid column in both tables.
CREATE VIEW tot_cred26 AS
SELECT year, semester, SUM(credits) as total_credits
FROM course AS c
INNER JOIN takes as t ON t.courseid = c.courseid
GROUP BY year, semester

Below Code may solve the problem:
CREATE VIEW tot_cred26
AS
SELECT year, semester, COUNT(credits) total_credits
FROM course INNER JOIN takes
group by year, semester
;

Related

aggregate function 'count' not returning expected results

I am using mySQL to query a mock university database. This is for a class so. The query I am trying to make is to this question:
Find the names and ids of the students who have taken exactly one
course in the Spring 2010 semester.
schema tables:
student(id, name, dept_name, total_cred)
takes(id, course_id, sec_id, semester, year, grade)
I can query the schema for all students who took classes in Spring of 2010 no problem. But where I run into trouble is the 'exactly one class' part.
select distinct s.id, name
from student s join takes
where semester = 'Spring' and
year = 2010;
I thought I would use a set operator like not in to compare that result to another that returns the number of classes taken by each student:
select distinct count(s.id) num_classes, name
from student s join takes
where semester = 'Spring' and
year = 2010
group by name
The problem is that when I run this query it returns the count of 8 for each name. But I have no idea where it is getting that number because there is nothing that occurs exactly 8 times.
My question(s):
1) am I going about this the right way?
2) If so what am I doing wrong to make the count return that way?
Try this:
select s.id, s.name
from student s join takes t on s.id = t.id
where t.semester = 'Spring' and
t.year = 2010
group by s.id, s.name
having count(*) = 1

Determine total cost per user from 3 Different Tables

I am working on a theatre booking system in MySql (My first SQL project). I have three tables:
Production (contains Title, BasicTicketPrice),
Performance (PerformanceDate, PerformanceTime, Title)
Booking (Email of person who booked, PerformanceDate, PerformanceTime, RowNumber).
Each person booked tickets for two or three performances (using their email to book).
I need to to write a query which will display the prices paid for all booked seats and I need to output the RowNumber, Email of person who booked and the Calculated Price.
I understand that I need to join these tables and make the query display a temporary column called Calculated Price but I don't know how to calculate the price.
I tried this:
SELECT DISTINCT b.RowNumber, b.Email, pr.BasicTicketPrice
FROM booking b, production pr performance p
WHERE p.Title=b.PerfDate*b.PerfTime*b.RowNumber;
SELECT CONCAT (PerfDate, PerfTime, RowNumber) AS BookingID FROM booking;
SELECT RowNumber, Email, CONCAT(PerfDate, PerfTime, RowNumber) AS BookingID FROM booking;
SELECT RowNumber, Email, CONCAT((CONCAT(PerfDate, PerfTime, RowNumber) AS BookingID
FROM booking)BasicTicketPrice*BookingID);
SELECT RowNumber, Email, CONCAT(PerfDate, PerfTime, RowNumber) AS BookingID INTEGER
FROM booking;
SELECT RowNumber FROM booking
LEFT JOIN (SELECT Title FROM performance WHERE '2017-11-01 19:00:00' Email IS NULL);
But it didn't work.
Any suggestions? I will be grateful for any ideas.
Assuming:
One row in Bookings per booked seat
Title to be a suitable primary key for Production
PerformanceDate, PerformanceTime to be a suitable primary composite key for Performance
You'll be looking to join the three tables together as per the keys assumed above. It seems you wish to group the bookings together per performance, by the person booking the tickets - if so, you'll need to use an aggregate to show the seat numbers (I've used GROUP_CONCAT to delimit them), as well as to COUNT the tickets purchased and multiply by the ticket cost.
SELECT
b.Email, prod.Title, per.PerformanceDate, per.PerformanceTime,
GROUP_CONCAT(RowNumber) AS BookedSeats,
COUNT(RowNumber) * prod.BasicTicketPrice AS TotalCost
FROM Booking b
INNER JOIN Performance per
ON b.PerformanceDate = per.PerformanceDate
AND b.PerformanceTime = per.PerformanceTime
INNER JOIN Production prod
ON per.Title = prod.Title
GROUP BY
b.Email, prod.Title, per.PerformanceDate, per.PerformanceTime, prod.BasicTicketPrice
ORDER BY prod.Title, per.PerformanceDate, per.PerformanceTime;
Technically, we should include all non-aggregated columns in the GROUP BY, hence prod.BasicTicketPrice is listed as well.

MySQL Query: How to join and group and I don't know what they're called

I'm relatively new to MySQL and have tried to teach myself how to use it so sorry if I'm not using the right terminology...
I have 2 tables: Students and Payments
The Payments table has a Student ID, Amount and Type (either Bond, Installment or Repair)
I am having trouble trying to figure out how to get a column for the sum of all bond payments and another for the sum of all instalment payments for each student and showing all the students that have a payment or not.
Alternatively, if you know any good guides for free (my budget is $0) that can help, that would be appreciated.
Thanks
Since you want all students, even if they don't have any matches in payments, you must use a LEFT JOIN.
select students.*, payments.type, SUM(payments.amount)
from students
left join payments on payments.student_id = students.id
group by students.id, payments.type
Note that this puts the different payment types each on their own row. Turning them into columns in the result is called pivoting. Some database systems have built-in ways to do this, but MySQL doesn't. Doing it requires knowing all the possible values of payments.type.
select students.*,
SUM(IF(payments.type = 'Bond', payments.amount, 0)) Bond,
SUM(IF(payments.type = 'Installment', payments.amount, 0)) Installment,
SUM(IF(payments.type = 'Repair', payments.amount, 0)) Repair
from students
left join payments on payments.student_id = students.id
group by students.id
I am suggesting you the query how you can get sum of all bond payments and installment payments.
Select student_id , sum(amount),Type from payments group by student_id,Type
To learn about the Mysql please refer the following sites.
http://www.tutorialspoint.com/mysql/
http://www.w3schools.com/sql/
http://www.mysqltutorial.org/

Query to find how many purchases were made this year, For each Artist

I need to list the Artist's Id_no, last name (lname) and how any purchases have been made on their releases this year. The only information about the purchases is different purchase dates.
My code so far :
SELECT id_no, lname, purchasedate AS num_ops
FROM Artist JOIN Sales ON Artist.id_no = Sales.artist
WHERE DATE_SUB(CURDATE(),INTERVAL 1 YEAR) <= purchasedate
However this only returns the Id_no's who have made sales, and I need all even if it is 0. On distrinctl name, and num_ops is a date of their first purchasedate. I need to alter this code to list how many purchases they have been involved in within this year. I've tried using COUNT(purchasedate) however this just returns one row. I wish the returning table to return:
1st Column: The Artist's ID Number
2nd Column: The Aritist's Last Name
3rd Column: The number of people who have purchased their CD's (which is a count of purchasedate)
I am struggling with the 3rd column majorly, and any help would be greatly appriciated.
You need:
a left join
to move the date condition into the ON clause of the JOIN
use the count(*) aggregating function
Like this:
SELECT id_no, lname, count(purchasedate) as num_ops
FROM Artist
LEFT JOIN Sales ON Artist.id_no = Sales.artist
AND DATE_SUB(CURDATE(),INTERVAL 1 YEAR) <= purchasedate
GROUP BY id_no, lname
The LEFT JOIN will ensure a row is returned for every artist even if there are no sales
By moving the date condition into the join that will still return a row for every artist even if there's no sale for the year. If the condition is left in the WHERE clause, that would filter out artists that didn't make sales in the last year.
A key point here is that the join condition may contain conditions unrelated to the keys involved - that's how you get conditional joins, which is what you want here to make the left join still function correctly

How to select the row of a minimum value of a group, while also using a where clause

I have a table that tracks attendance in a course. The columns are the courseid, lesson, personid, and date. I have a query (below) that extracts the earliest date a person appears along with the associated course, lesson, and personid. This is used to determine when a person started a particular course and ensure they started with the first lesson. This works fine, but where I am stuck is running this query per course. For example, finding the first date each person in a particular course started it rather than for every course. Right now I am just running the more general query and filtering it in the biz layer.
I obfuscated this a bit so forgive any typos:
select a.courseid,
a.lesson,
a.personid,
a.thedate
from (select personid,
min(thedate) as earliestdate
from attendance
group by personid) as x
inner join attendance as a on (a.personid = x.personid and a.thedate = x.thedate)
Just group over person_id, course in the inner query:
select a.courseid, a.lesson, a.personid, a.thedate
from (
select personid, courseid, min(thedate) as earliestdate
from attendance
group by personid, courseid
) as x
inner join attendance as a
on (a.personid = x.personid and
a.thedate = x.thedate and
a.courseid=x.course_id)
I have a small doubt here. Currently all the information is maintained in single data object/table. How would it be if we have different data model like below...?
Objext1:
Course table: Course details having lession with a relation
Student table: Contains student details.
Will the querying would be simplified in this way....?
Sorry if anything sounds immatur...
Regards,
UDAY