Oracle SQL join three tables and group by column - sql

I have three tables and I want a query te select teacher names and the number of classes each teacher has reserved.
teacher:
| idt | name |
class:
| idc | name |
reserve:
| idc | idt |
My query:
select
t.name, count(distinct(r.idc))
from
teacher t
join
reserve r
on
r.idt = t.idt
join
class c
on
c.idc = r.idc
group by r.idc
When I run this I get the followin error: not a group by expression.

The group by clause needs to contain all non-aggregated columns from the select statement; in your case it should be t.name. Also, distinct is not a function but a keyword and should not have parentheses.
select
t.name,
count(distinct r.idc) as number_of_classes
from
teacher t
join
reserve r on r.idt = t.idt
join
class c on c.idc = r.idc
group by
t.name

Related

SQL to concatenate two columns and join two tables

Table person:
| id | f_name | l_name |
Table sales:
| id | amount | date | itemname |
I have a problem joining the two tables which concat f_name and last_name as fullname column, and joining with table sales. Here id is same on both tables.
Output:
| itemname| date |fullname |
What I have tried:
select *
from
(select
concat(f_name, l_name) as fullname
from
tblperson) p
left join
select itemname, date
from table sales s on s.id = p.id
It should actually be
SELECT table_sales.*, concat(table_person.f_name, table_person.l_name) as fullname
FROM table_person
LEFT JOIN table_sales
ON table_person.id = table_sales.id
have not tested this but that is the syntax
you're missing a field like person_id in your sales table (which references the id field in the person table). You can then use a join to properly join the data together.
You are so close. Try this
select p.*,concat(f_name,l_name)as fullname, s.itemname,s.date, s.amount
from person p left join
sales s on s.id=p.id
Here ia good read on sql join.
https://www.w3schools.com/sql/sql_join.asp

SQL query to retrieve average of different aggregation type in single query

This is my data model:
I need to get name, surname and personal votes average of all students in classroom that have the average lower then the votes average of all students in classroom. Following the desired output:
+---------+------+--------+-------------+---------------+
| surname | name | class | class_avg | studend_avg |
+---------+------+--------+-------------+---------------+
| b | b | 1 | 4.1250 | 2.7500 |
+---------+------+--------+-------------+---------------+
I wrote following query that works correctly in mariadb database:
SELECT student.surname, student.name, student.classroom, classroom.average AS classroom_average, AVG(vote.vote) AS student_average
FROM (student INNER JOIN vote ON student.fiscalcode = vote.fiscalcode)
INNER JOIN
(select student.classroom AS classroom, AVG(vote.vote) AS average
FROM student INNER JOIN vote ON student.fiscalcode = vote.fiscalcode
GROUP BY student.classroom) AS classroom
ON student.classroom=classroom.classroom
GROUP BY student.surname, student.name, student.classroom, classroom.average
HAVING AVG(vote.vote) < classroom.average;
But I have this error in MS Access:
Your Query does not include the specified expression "AVG(vote.vote)/AVG(vote.vote) < classroom.average" as part of an aggregate function
There are some other easier method to write this query?
Consider:
SELECT StudentAvg.fiscalcode, student.name, student.surname, StudentAvg.AvgOfvote, ClassAvg.AvgOfvote
FROM ((SELECT student.classroom, student.fiscalcode, Avg(vote.vote) AS AvgOfvote
FROM student INNER JOIN vote ON student.fiscalcode = vote.fiscalcode
GROUP BY student.classroom, student.fiscalcode) As StudentAvg INNER JOIN (SELECT student.classroom, Avg(vote.vote) AS AvgOfvote
FROM vote INNER JOIN student ON vote.fiscalcode = student.fiscalcode
GROUP BY student.classroom) AS ClassAvg ON StudentAvg.classroom = ClassAvg.classroom) INNER JOIN student ON StudentAvg.fiscalcode = student.fiscalcode
WHERE (((StudentAvg.AvgOfvote)<[ClassAvg]![AvgOfvote]));

Access SQL JOIN with subquery

Can someone tell me how I can convert this query to work in MS Access?
SELECT Shooters.idShooters, Shooters.firstname, Shooters.lastname, JoinedContingent.Count, JoinedShots.Count
FROM Shooters
INNER JOIN
(SELECT Shooters.idShooters, Count(Contingent.idContingent) AS Count
FROM Shooters LEFT JOIN Contingent ON Shooters.idShooters = Contingent.fidShooter
GROUP BY Shooters.idShooters)
AS JoinedContingent ON JoinedContingent.idShooters = Shooters.idShooters
INNER JOIN
(SELECT Shooters.idShooters, Count(Shots.idShots) AS Count
FROM Shooters LEFT JOIN Shots ON Shooters.idShooters = Shots.fidShooters
GROUP BY Shooters.idShooters)
AS JoinedShots ON JoinedShots.idShooters = Shooters.idShooters;
Background information:
I would like to count the foreign key occurrences for each Shooter in the table Contingent and Shots. The result should look like this:
idShooters | firstname | lastname | Count | Count
____________________________________________________________
1 John Doe 0 10
2 Jane Doe 1 20
.
.
.
I think this is what you want:
SELECT s.idShooters, s.firstname, s.lastname,
NZ(c.Count, 0), NZ(sh.Count, 0)
FROM (Shooters as s LEFT JOIN
(SELECT c.fidShooter, Count(*) AS Count
FROM Contingent as c
GROUP BY c.fidShooter
) as c
ON s.idShooters = c.fidShooter
) LEFT JOIN
(SELECT sh.fidShooters, Count(*) AS Count
FROM Shots as sh
GROUP BY sh.fidShooters
) as sh
ON s.idShooters = sh.fidShooters;
Note that I moved the outer join to the outer query. Actually, no joins are needed in the subqueries, so don't bother.

SQL Joins with 4 tables

I have a problem here and I got a bit confused with outer/inner joins and multiple conditions
We have 4 tables with - columns:
table_cars - id | brand | type | license
table_equipments - id | name | description
table_distances - id_car | date | distance
table_cars_equipments - id_car | id_equipment
First query should show all cars that have equipment "fire extinguisher" and have been driving yesterday.
I have tried to write this query:
SELECT table_cars_equipments.id_car
FROM table_equipments
INNER JOIN table_cars_equipments
ON table_equipments.id = table_cars_equipments.id_equipment
AND table_equipments.name LIKE 'fire extinguisher';
Though I am still confused how to add the cars which had been driving yesterday, I don't know how to make the connection with the table table_distances.
Add another JOIN with the table table_cars and another one to the table table_distances. Then add a condition to the WHERE clause to get only those cars that have been driving yesterday. Something like this:
SELECT
c.id,
c.brand,
c.type,
c.license
ce.id_car,
...
from table_equipments AS e
INNER JOIN table_cars_equipments AS ce ON e.id = ec.id_equipment
INNER JOIN table_cars AS c ON c.id = ce.id_car
INNER JOIN table_distances AS d ON d.id_car = c.id
WHERE e.name LIKE 'fire extinguisher'
AND d.date = ?;
Note that: I used aliases for the table c, e etc, instead of the tables' full names.

Select Query Joining 3 Tables

I've 3 Tables
Personel : id, name
Department : id, name
Match_Dept_Per : dept_id, pers_id, workInfo
Foreign Keys :
dept_id --> Department.id
pers_id --> Personel.id
Example Data :
Personel :
1, Emir Civas
2, Sercan Tuncay
Department :
1, Sales
2, Planning
Match_Dept_Per :
1,1,Manager
What I'm trying to do is, listing peoples names, their department names and workInfos like:
ID | Pers. Name | Dept Name | Work Info
---------------------------------------
1 | Emir Civas | Sales | Manager
I can do this with a simple select query:
select p.id, p.name, d.name, m.workInfo
from personel p, department d, match_dept_per m
where p.id = m.pers_id and d.id = m.dept_id;
Here is sample fiddle of my schema and this query.
However what I need is to display other persons that their id's are not inserted to match_dept_per table. And Set "Unknown" As the Null Values. Like:
ID | Pers. Name | Dept Name | Work Info
------------------------------------------
1 | Emir Civas | Sales | Manager
2 | Sercan Tuncay | Unknown | Unknown
Since I'm Using Match_Dept_Per Table, If Personel ID isn't Added, I can't do anything.
Any suggestions ?
Use left outer join to include all persons even if they are not associated with the other tables:
select p.id,
p.name,
ifnull(d.name, 'Unknown') DepName,
ifnull(m.workInfo, 'Unknown') workInfo
from personel p
left outer join match_dept_per m
on p.id = m.pers_id
left outer join department d
on d.id = m.dept_id
Here is a demo fiddle.
As you seem to use MS SQL, you might need to use isnull() instead of ifnull(). But I would ommit that anyway because I think it's better to have a NULL in the code where you use the data (Java, C#, whatever). You can control the output there.