How to retrieve data based on this criteria? - mysql

I have the following tables:
Payment Table
CREATE TABLE Payment (
PayID INTEGER,
PayName CHAR (55),
PaymentDescription VARCHAR (100),
Primary Key (PayID)
);
Users Table
CREATE TABLE Users (
UserID INTEGER,
UserFirst CHAR (40),
UserLast CHAR (40),
UserName VARCHAR (40),
UserAddress VARCHAR (35),
UserBirthdate DATE,
UserGender CHAR (1),
UserEmail VARCHAR (35),
PRIMARY KEY (UserID)
);
Genre Table
CREATE TABLE GENRE (
GenreID Integer,
Name CHAR(45),
Description VARCHAR (250),
PRIMARY KEY (GenreID)
);
Song Table
CREATE TABLE SONG (
SongID Integer,
GenreID Integer,
Title VARCHAR (50),
Album VARCHAR (40),
Duration TIME,
ReleaseYear DATE,
PRIMARY KEY (SongID),
CONSTRAINT foreignkey_holds_GenreID FOREIGN KEY (GenreID)
REFERENCES Genre(GenreID)
);
Song_Users Table
CREATE TABLE Song_Users (
UserID INTEGER,
SongID Integer,
PRIMARY KEY (UserID,SongID),
CONSTRAINT fk_users_song_user FOREIGN KEY (UserID)
REFERENCES Users(UserID),
CONSTRAINT fk_users_song_song FOREIGN KEY (SongID)
REFERENCES SONG(SongID)
);
Payment_Users Table
CREATE TABLE Payment_Users (
UserID INTEGER,
PayID INTEGER,
PRIMARY KEY (UserID,PayID),
CONSTRAINT fk_users_payment_user FOREIGN KEY (UserID)
REFERENCES Users(UserID),
CONSTRAINT fk_users_payment_pay FOREIGN KEY (PayID)
REFERENCES Payment(PayID)
);
And I have also populated the tables:
Payments
INSERT INTO Payment (PayID,PayName,PaymentDescription) VALUES (1, 'Visa', 'Applies to VISA Debit, Electron, Credit')
INSERT INTO Payment (PayID,PayName,PaymentDescription) VALUES (2, 'Mastercard', 'Applies across all types')
INSERT INTO Payment (PayID,PayName,PaymentDescription) VALUES (3, 'PayPal', 'Payment made using PayPal')
INSERT INTO Payment (PayID,PayName,PaymentDescription) VALUES (4, 'ApplePay', 'Payment method for IOS users')
Users
INSERT INTO Users (UserID, UserFirst, UserLast, UserName, UserAddress, UserBirthdate, UserGender, UserEmail) VALUES (1, 'Jane', 'Johnson', 'jjsweet135', '10 House Wood Street',19970321, 'F', 'jj1997#gmail.com')
INSERT INTO Users (UserID, UserFirst, UserLast, UserName, UserAddress, UserBirthdate, UserGender, UserEmail) VALUES (2, 'Joe', 'Watson', 'joewatson98', '21 House Red Street',19980414, 'M', 'joewatson1998#gmail.com')
INSERT INTO Users (UserID, UserFirst, UserLast, UserName, UserAddress, UserBirthdate, UserGender, UserEmail) VALUES (3, 'Katie', 'Davies', 'katiethebest425', '17 House Fun Street',20000318, 'F', 'katiebest452#hotmail.com')
INSERT INTO Users (UserID, UserFirst, UserLast, UserName, UserAddress, UserBirthdate, UserGender, UserEmail) VALUES (4, 'Tom', 'Branson', 'tommylad100', '27 House Church Street',20010719, 'M', 'tommylad35#orange.com')
Genre Table
INSERT INTO Genre (GenreID, Name, Description) VALUES
(1, 'Electro Swing', 'A musical journey set in the 90s')
INSERT INTO Genre (GenreID, Name, Description) VALUES
(2, 'House', 'When the beat shakes your house')
INSERT INTO Genre (GenreID, Name, Description) VALUES
(3, 'Classical', 'To stimulate neural activity in your brain')
INSERT INTO Genre (GenreID, Name, Description) VALUES
(4, 'Rap', 'Experience the streets from the comfort of your own home')
INSERT INTO Genre (GenreID, Name, Description) VALUES
(5, 'Pop', 'Follow the status quo')
Song Table
INSERT INTO SONG (SongID, GenreID, Title, Album, Duration, ReleaseYear) VALUES (1, 1, 'Swing the Electro', 'Electro Swing Vol 1', 11537, 19970316)
INSERT INTO SONG (SongID, GenreID, Title, Album, Duration, ReleaseYear) VALUES (2, 2, 'This is my House', 'UK House Anthem', 11454, 19990419)
INSERT INTO SONG (SongID, GenreID, Title, Album, Duration, ReleaseYear) VALUES (3, 3, 'Candy Shop', '50 Cent Classics', 2254, 20010324)
INSERT INTO SONG (SongID, GenreID, Title, Album, Duration, ReleaseYear) VALUES (4, 4, 'Mozart', 'Classical strokes', 44524, 18000225)
INSERT INTO SONG (SongID, GenreID, Title, Album, Duration, ReleaseYear) VALUES (5, 5, 'Katy Perry', 'Baby you are a Firework', 13524, 20050324)
INSERT INTO SONG (SongID, GenreID, Title, Album, Duration, ReleaseYear) VALUES (6, 5, 'One Direction', 'We are the one', 013204, 20060211)
INSERT INTO SONG (SongID, GenreID, Title, Album, Duration, ReleaseYear) VALUES (7, 5, 'Chainsmokers', 'In the back seat of your rover', 33544, 20160123)
INSERT INTO SONG (SongID, GenreID, Title, Album, Duration, ReleaseYear) VALUES (8, 5, 'Justin Bieber', 'Teenage dream', 22222, 20150325)
Song_Users Table
INSERT INTO Song_Users (UserID, SongID) VALUES (1,1)
INSERT INTO Song_Users (UserID, SongID) VALUES (2,2)
INSERT INTO Song_Users (UserID, SongID) VALUES (3,3)
INSERT INTO Song_Users (UserID, SongID) VALUES (4,4)
INSERT INTO Song_Users (UserID, SongID) VALUES (4,1)
INSERT INTO Song_Users (UserID, SongID) VALUES (4,2)
INSERT INTO Song_Users (UserID, SongID) VALUES (4,3)
INSERT INTO Song_Users (UserID, SongID) VALUES (4,5)
INSERT INTO Song_Users (UserID, SongID) VALUES (4,6)
INSERT INTO Song_Users (UserID, SongID) VALUES (4,7)
INSERT INTO Song_Users (UserID, SongID) VALUES (4,8)
Payment_Users Table
INSERT INTO Payment_Users VALUES (1,1)
INSERT INTO Payment_Users VALUES (2,2)
INSERT INTO Payment_Users VALUES (3,3)
INSERT INTO Payment_Users VALUES (4,3)
I need to find the most popular genre of music for Females (F). I can't seem to retrieve this information, because there is no corresponding Foreign Key for Genre(GenreID).
How could I create the query to get the most popular genre amongst females?
EDIT
SELECT Users.UserID, UserGender, SongID, GenreID FROM Users, Song_Users, Song
WHERE Users.UserID = Song_Users.UserID
AND
WHERE Genre.GenreID = Song.GenreID;
I am trying to link GenreID with SongID, but I am not sure how to do it. There is a link with a foreign key, but not in the Genre table, but only in the Song Table. My logic was to select the user, their gender, their songs and then the corresponding genre. Then I could use something like a HAVING CLAUSE to select stricly females and using a COUNT (Genre) and the appropriate GROUPBY function

As per the comments above, there is a huge amount of unnecessary information in this question. A set of sample data and evidence of effort on your part should be included, but the commands used to populate the tables are irrelevant.
I am assuming the following definition of popularity: The greatest number of users that have purchased songs in a given genre.
From what you have above, then you can accomplish what you are looking for with inner joins across four tables:
SELECT
count(u.UserID) as 'popularity',
g.Name as 'genre'
FROM
Users u INNER JOIN
Song_Users su INNER JOIN
SONG s INNER JOIN
GENRE g
ON
u.UserID = su.UserID,
su.SongID = s.SongID,
s.GenreID = g.GenreID
WHERE
u.UserGender = 'F'
GROUP BY
g.Name
ORDER BY
count(u.UserID) DESC

You will Inner join In MYSQL,
Select Field names from Songs Innerjoin users.user_id ON songs.user_id
Innerjoin Genre.Genre_id ON songs.Genre_id
You see type your table names and columns names correctly . You will get the correct result.

SELECT COUNT(g.`GenreID`) AS popularity, g.`Name` FROM genre g, song_users su, song s, users u WHERE
u.`UserGender` = 'F'
AND su.`UserID` = u.`UserID`
AND s.`SongID` = su.`SongID`
AND g.`GenreID` = s.`GenreID`
GROUP BY g.`GenreID`
The popularity would give you the genres name and their count as popularity, the highest count is the most famous.

Related

SQL query to link 3 tables with all contents

I have created 3 sample tables which I want to link together, as well as a URL to the case in DB Fiddle with mySQL 8.0.
https://www.db-fiddle.com/f/6mmFrw3JTWkVVznaH5juNp/0
The goal is that I get the prices for the stores "Amazon" and "Ebay" for all items from table "products_info". As soon as no prices are available in my "merchants_products" table, the SKU for the store should still be displayed. So at the end not 3 rows, but 4 rows should be displayed.
Table 1:
merchants contains all locations where my items are being sold.
Table2:
merchants_products contains all the items plus prices that I sell in the different locations.
Table3:
products_info contains all the items I want to get my information about.
create table merchants_products
(
SKU char(10) null,
MERCHANT_ID int null,
PRICE int null
);
INSERT INTO merchants_products (SKU, MERCHANT_ID, PRICE) VALUES ('13749461', 1, 3);
INSERT INTO merchants_products (SKU, MERCHANT_ID, PRICE) VALUES ('13753824', 1, 5);
INSERT INTO merchants_products (SKU, MERCHANT_ID, PRICE) VALUES ('13749461', 2, null);
INSERT INTO merchants_products (SKU, MERCHANT_ID, PRICE) VALUES ('13753770', 2, 4);
INSERT INTO merchants_products (SKU, MERCHANT_ID, PRICE) VALUES ('13749461', 3, 3);
INSERT INTO merchants_products (SKU, MERCHANT_ID, PRICE) VALUES ('13753770', 3, 4);
INSERT INTO merchants_products (SKU, MERCHANT_ID, PRICE) VALUES ('13753824', 3, 5);
create table merchants
(
ID int null,
NAME varchar(255) null
);
INSERT INTO merchants (ID, NAME) VALUES (1, 'amazon');
INSERT INTO merchants (ID, NAME) VALUES (2, 'ebay');
INSERT INTO merchants (ID, NAME) VALUES (3, 'tesco');
create table product_info
(
SKU char(10) null,
NAME varchar(255) null
);
INSERT INTO product_info (SKU, NAME) VALUES ('13749461', 'Artikel1');
INSERT INTO product_info (SKU, NAME) VALUES ('13753770', 'Artikel2');
SELECT
pi.SKU,
mp.PRICE,
mc.NAME
FROM product_info pi
LEFT JOIN merchants_products mp
ON mp.SKU= pi.SKU and mp.MERCHANT_ID IN (1,2)
LEFT JOIN merchants mc
ON mc.ID = mp.MERCHANT_ID

Sum sales from different tables

I have 5 tables related to sales. Three of them are like this:
Product_table_image
They are called product_a, product_b, product_c
The other tables are the time_id table which contains the reference for the date_id and the customers' table, which contains the details of customers.
time_id table
and
customer_table
The 3 tables refer to the sales of different products, but the products are not important in this context, because what I need is to sum up all the values per month per customer. There are cases when one or more customers might not have made a purchase of a certain product, which means not all customers ids will be in all products tables and that's what I can't figure out how to solve. It seems that my code is only able to fetch and sum when the clients have made purchases in all 3 tables.
So this is what I was able to come up with:
SELECT C.customer_id, ROUND((A.pa + B.pa + C.pc)* 1, 2) AS total,C.month_id
FROM (SELECT customer.customer_id, SUM(product_a.amount) AS pa , time_id.month_id FROM customer
INNER JOIN product_a on customer.customer_id = product_a.customer_id
INNER JOIN time_id on product_a.date_id = time_id.date_id
GROUP BY customer.customer_id, time_id.month_id) AS A
CROSS JOIN
(SELECT customer.customer_id, SUM(product_a.amount) AS pb , time_id.month_id FROM customer
INNER JOIN product_b on customer.customer_id = product_b.customer_id
INNER JOIN time_id on product_b.date_id = time_id.date_id
GROUP BY customer.customer_id, time_id.month_id) AS B
CROSS JOIN
(SELECT customer.customer_id, SUM(product_a.amount) AS pc , time_id.month_id FROM customer
INNER JOIN product_c on customer.customer_id = product_c.customer_id
INNER JOIN time_id on product_c.date_id = time_id.date_id
GROUP BY customer.customer_id, time_id.month_id) AS C
GROUP BY C.month_id, C.customer_id
ORDER BY C.month_id;
I've been stuck in it for a while, so any help is appreciated!
I have setup the tables and some sample data to make it more real.
create table month(id int, name varchar(20), primary key (id));
insert into month (id, name) values (1, 'January'),(2,'February'),(3,'March'),(4,'April');
create table year(id int, name varchar(4), primary key (id));
insert into year(id, name) values (2019, '2019'),(2020,'2020'),(2021,'2021');
create table time (id int, month_id int, year_id int, primary key (id));
alter table time add constraint fk_month FOREIGN KEY (month_id) REFERENCES month (id);
alter table time add constraint fk_year FOREIGN KEY (year_id) REFERENCES year (id);
insert into time (id, year_id, month_id) values
(1, 2019, 1),(2, 2019, 2),(3,2019,3),(4,2019,4),
(5, 2020, 1),(6, 2020, 2),(7,2020,3),(8,2020,4),
(9, 2021, 1),(10, 2021, 2),(11,2021,3),(12,2021,4);
create table customers (id int, name varchar(100), city varchar(100), country varchar(100), primary key (id));
insert into customers (id, name, city, country) values
(1, 'Google', 'San Francisco', 'US'),
(2, 'Ambev', 'São Paulo', 'BR'),
(3, 'Merck', 'Darmstadt', 'GE');
create table sales_of_product_a (id int, customer_id int, date_id int, amount decimal(10,2), primary key (id));
alter table sales_of_product_a add constraint fk_pa_time FOREIGN KEY (date_id) REFERENCES time (id);
-- only customer 1 - Google and 3 - Merck purchased product A
insert into sales_of_product_a (id, customer_id, date_id, amount) values
(1, 1, 1, 100.10),(2,1,2,200.20),(3,1,3,300.30),(4,1,4,400.40),
(5, 1, 5, 500.50),(6,1,6,600.60),(7,1,7,700.70),(8,1,8,800.80),
(9, 3, 1, 130.10),(10,3,2,230.20),(11,3,3,330.30),(12,3,4,430.40),
(13, 3, 5, 530.50),(14,3,6,630.60),(15,3,7,730.70),(16,3,8,830.80);
create table sales_of_product_b (id int, customer_id int, date_id int, amount decimal(10,2), primary key (id));
alter table sales_of_product_b add constraint fk_pb_time FOREIGN KEY (date_id) REFERENCES time (id);
-- only customer 1 - Google purchased product B
insert into sales_of_product_b (id, customer_id, date_id, amount) values
(1, 1, 1, 100.10),(2,1,2,200.20),(3,1,3,300.30),(4,1,4,400.40),
(5, 1, 5, 500.50),(6,1,6,600.60),(7,1,7,700.70),(8,1,8,800.80),
(9, 1, 9, 900.90),(10,1,10,1000.01),(11,1,11,1100.11),(12,1,12,1200.12);
create table sales_of_product_c (id int, customer_id int, date_id int, amount decimal(10,2), primary key (id));
alter table sales_of_product_c add constraint fk_pc_time FOREIGN KEY (date_id) REFERENCES time (id);
-- only customer 3 - Merck purchased product C
insert into sales_of_product_c (id, customer_id, date_id, amount) values
(1, 3, 1, 130.10),(2,3,2,230.20),(3,3,3,330.30),(4,3,4,430.40),
(5, 3, 5, 530.50),(6,3,6,630.60),(7,3,7,730.70),(8,3,8,830.80),
(9, 3, 9, 930.90),(10,3,10,1030.01),(11,3,11,1130.11),(12,3,12,1230.12);
The SQL you might be looking for would be something like.
with all_sales as (
select pa.customer_id, tt.month_id, sum(pa.amount) as amount from sales_of_product_a pa inner join time tt on (pa.date_id = tt.id) where tt.year_id = 2019 group by pa.customer_id, tt.month_id
union all
select pb.customer_id, tt.month_id, sum(pb.amount) as amount from sales_of_product_b pb inner join time tt on (pb.date_id = tt.id) where tt.year_id = 2019 group by pb.customer_id, tt.month_id
union all
select pc.customer_id, tt.month_id, sum(pc.amount) as amount from sales_of_product_c pc inner join time tt on (pc.date_id = tt.id) where tt.year_id = 2019 group by pc.customer_id, tt.month_id
),
sales_per_customer_per_month as (
-- summary of all sales of all products per customer per month
select customer_id, month_id, sum(amount) as amount from all_sales group by customer_id, month_id
),
customers_month as (
select c.id, c.name, c.city, c.country, m.id as month_id, m.name as month_name from customers c inner join month m on true
)
select c.id,c.name,c.city,c.country,c.month_id, coalesce(s.amount,0) as amount, sum(coalesce(s.amount,0)) over (partition by c.id order by c.id,c.month_id) as total
from customers_month c
left join sales_per_customer_per_month s on (s.customer_id = c.id and s.month_id = c.month_id)
order by c.id,c.month_id;
The result of query above is following.
The concepts used are linked below.
Window Functions:
https://dev.mysql.com/doc/refman/8.0/en/window-functions.html
Common Table Expressions (CTE):
https://www.mysqltutorial.org/mysql-cte/

How to combine and get sum from three different related tables in MySQL?

There are three related tables:
operations (id, name)
pricelists (id, operations_id (link to operations table), cost)
accounting (id, pricelists_id (link to pricelists table), quantity)
How to get table, like
NAME SUMMARY_COST SUMMARY_QUANTITY
milling result of 2*750 2
threading result of 1*444 1
... ... ...
overall 2*750+1*444+... 2+1+...
I trying to group for two tables at a start:
select operations.name, sum(pricelists.cost) total
from operations
left join pricelists on pricelists.operations_id*accounting_quantity = operations.id*accounting.quantity
group by operations.id
but it is not worked yet
A little database:
CREATE TABLE operations (id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (100));
CREATE TABLE pricelists (id INT PRIMARY KEY, operations_id INT NOT NULL, cost DECIMAL(10,2),
FOREIGN KEY (operations_id) REFERENCES operations (id));
CREATE TABLE accounting (id INT PRIMARY KEY, pricelists_id INT NOT NULL, quantity INT,
FOREIGN KEY (pricelists_id) REFERENCES pricelists (id));
INSERT INTO operations (name) VALUES
('milling'),
('threading'),
('grinding'),
('welding'),
('brazing'),
('soldering'),
('riveting');
INSERT INTO pricelists (id, operations_id, cost) VALUES
(1, 2, 750),
(2, 1, 444),
(3, 3, 123),
(4, 4, 450),
(5, 5, 375),
(6, 6, 250),
(7, 7, 232);
INSERT INTO accounting (id, pricelists_id, quantity) VALUES
(1, 7, 2),
(2, 2, 5),
(3, 4, 2),
(4, 1, 1),
(5, 3, 4);
Consder:
select o.name, sum(a.quantity * pl.cost) total, sum(a.quantity) quantity
from operations o
left join pricelists pl on pl.operations_id = o.id
left join accounting a on a.pricelists_id = pl.id
group by o.name
You can generate the summary row by just adding with rollup at the very end of the query.

query to find diff between two records

I have following tables
movies
- id
details
- user_id
- movie_id
- rating
users
- id
detail belongs to user and movie
I want to find the the diff between the rating of two users say id 3,10
simply I want answer of this
sum(10-(user1.rating - user2.rating))
where rating is > 0
i.e both users should have given at-least non zero rating
select
d1.movie_id
, d1.rating as user1Rating
, d2.rating as user2Rating
, abs(d1.rating - d2.rating)
from
details d1
inner join details d2 on d1.movie_id = d2.movie_id
where d1.user_id = 1
and d2.user_id = 2
See it working live in an sqlfiddle.
CREATE TABLE ratings
( userId int, movieId int, rating int)
INSERT INTO ratings (userId, movieId, rating) VALUES
(3, 1, 5), (10, 1, 8),
(3, 2, 10), (10, 2, 3)
SELECT r1.movieId, (r1.rating - r2.rating) FROM ratings as r1
INNER JOIN ratings as r2 on r1.movieId = r2.movieId
WHERE r1.userId = 3 and r2.userId = 10
DECLARE #UserRating1 int
DECLARE #UserRating2 int
DECLARE #UserID1 int
DECLARE #UserID2 int
DECLARE #MovieID int
SET #MovieID = 99
SET #UserID1 = 3
SET #UserID2 = 10
SET #UserRating1 = (SELECT Rating FROM details WHERE movie_id = #MovieID AND user_id = #UserID1 AND Rating > 0)
SET #UserRating2 = (SELECT Rating FROM details WHERE movie_id = #MovieID AND user_id = #UserID2 AND Rating > 0)
PRINT #UserRating1 - #UserRating2
Update: I replace the syntax from MSSQL to MySql
You can check this on SQL Fiddle:
create table movies (id int);
insert into movies (id) values (1);
insert into movies (id) values (2);
insert into movies (id) values (3);
insert into movies (id) values (4);
insert into movies (id) values (5);
create table users (id int);
insert into users (id) values (1);
insert into users (id) values (2);
insert into users (id) values (3);
insert into users (id) values (4);
insert into users (id) values (5);
insert into users (id) values (10);
create table details (user_id int, movie_id int, rating int);
insert into details (user_id, movie_id, rating) values (3,1,1);
insert into details (user_id, movie_id, rating) values (3,2,2);
insert into details (user_id, movie_id, rating) values (3,3,3);
insert into details (user_id, movie_id, rating) values (3,4,1);
insert into details (user_id, movie_id, rating) values (3,5,4);
insert into details (user_id, movie_id, rating) values (10,1,3);
insert into details (user_id, movie_id, rating) values (10,2,1);
insert into details (user_id, movie_id, rating) values (10,3,2);
insert into details (user_id, movie_id, rating) values (10,4,1);
insert into details (user_id, movie_id, rating) values (10,5,5);
and
select
sum(10-(details1.rating - details2.rating))
from
movies
inner join details details1 on movies.id = details1.movie_id
inner join users user1 on details1.user_id = user1.id
inner join details details2 on movies.id = details2.movie_id
inner join users user2 on details2.user_id = user2.id
where
(user1.id=3)
and
(user2.id=10)
and
(details1.rating is not null) and (details1.rating > 0)
and
(details2.rating is not null) and (details2.rating > 0)

Select columns other than the one specified in GROUP BY clause

Is there a way to select columns other the one specified in the group by clause?
Let's say I have the following schema:
Student(id, name, age), Course(id, name, credit), Enrollment(student_id, course_id, grade)
I want to query for each course the following: course's name, student_count.
I came up with workaround, but I was wondering if there's a cleaner way to do this:
SELECT MAX(c.name), COUNT(distinct e.student_id)
FROM Enrollment e
INNER JOIN Course c ON c.id = e.course_id
GROUP BY e.course_id;
You might want to copy this DDL, adjust it to match your schema, and paste it into your question.
create table Student(
student_id integer primary key,
student_name varchar(35) not null,
age int not null default 20
);
create table Course(
course_id integer primary key,
course_name varchar(35) not null,
credit integer not null default 3
);
create table Enrollment(
student_id integer not null references Student (student_id),
course_id integer not null references Course (course_id),
primary key (student_id, course_id),
grade char(1) not null
);
insert into student values
(1, 'a', 20),
(2, 'b', 20),
(3, 'c', 20);
insert into course values
(1, 'course 1', 3),
(2, 'course 2', 3),
(3, 'course 3', 3);
insert into enrollment values
(1, 1, 'b'),
(2, 1, 'b'),
(3, 1, 'b'),
(1, 2, 'b'),
(2, 2, 'b'),
(3, 3, 'b');
Now, you can get the number of students enrolled in each course by querying only the "enrollment" table.
select course_id, count(student_id) num_students
from enrollment
group by course_id
order by course_id;
course_id num_students
--
1 3
2 2
3 1
All that remains is to get the corresponding course name. To do that, you just join the table "Course" with the query we just wrote.
select course.course_name, course_enrollment.num_students
from course
inner join (select course_id, count(student_id) num_students
from enrollment
group by course_id) course_enrollment
on course.course_id = course_enrollment.course_id;
course_name num_students
--
course 1 3
course 3 1
course 2 2
No, you can't. But you can extend GROUP BY with c.name:
SELECT MAX(c.name), COUNT(distinct e.student_id)
FROM Enrollment e
INNER JOIN Course c ON c.id = e.course_id
GROUP BY e.course_id, c.name
Because e.course_id is unique, it won't change results.