MySQL - Left and Self Join in single query - mysql

As the title states I am trying to Left Join information from table B, but then also show matching information in table A, thats not associated in table B. Below is my query but it's currently only returning the inner join.
SELECT
concat(u.firstname, ' ', u.lastname) AS clientName,
u.email AS clientEmail,
u.created_at AS signedUp,
u.refferedby AS referredBy,
concat(t.firstname, ' ', t.lastname) AS trainerWho,
t.email AS trainerWhoEmail,
concat(usr.firstname, ' ', usr.lastname) AS clientWho,
usr.email as clientWhoEmail
FROM users u
LEFT JOIN trainers t ON u.externalid = t.hashId
INNER JOIN users usr ON u.externalid = usr.hashId
WHERE u.refferedby IS NOT NULL
AND DATE(u.created_at) >= CURDATE() -7
ORDER BY(u.created_at);

Related

How do I display two columns with multiple values and separate the occurances with a WHERE clause

This is my SQL query I am trying to select the names of employees from the employee table 'T' as trainer and 'S' as student. Where each student is linked to a trainer.
SQL query:
SELECT
cc.CourseName,
FORMAT(cs.StartDate, 'dd/MM/yyyy') AS 'Start Date',
FORMAT(cs.EndDate, 'dd/MM/yyyy') AS 'End Date',
a.AcademyName,
r.RoomName,
(SELECT e.FirstName + ' ' + e.LastName WHERE e.EmployeeType = 'T') AS 'Trainer',
(SELECT e.FirstName + ' ' + e.LastName WHERE e.EmployeeType = 'S') AS 'Student'
FROM
Employees e
INNER JOIN
CourseScheduleTrainers cst ON e.EmployeeID = cst.EmployeeID
INNER JOIN
CourseScheduleAttendees csa ON cst.TrainerID = csa.TrainerID
INNER JOIN
CourseCatalog cc ON csa.CourseCatalogID = cc.CourseCatalogID
INNER JOIN
CourseSchedule cs ON cc.CourseScheduleID = cs.CourseScheduleID
INNER JOIN
Rooms r ON cs.RoomsID = r.RoomsID
INNER JOIN
Academies a ON r.AcademyID = a.AcademyID;
This is what it is returning:
And this is an ERD of the database I am am trying to create. Essentially Course Attendees can also be classed as employees and they are labelled using the Employee Type
Entity Relationship Diagram:
I thought it was a simple case of sub querying but that doesn't seem to work.
Consider joining Employees twice and re-order the FROM and JOIN clauses to start with the main granular table, CourseScheduleAttendees, where other tables serve as lookups in a hub-spoke fashion:
SELECT cc.CourseName
,FORMAT(cs.StartDate, 'dd/MM/yyyy') AS 'Start Date'
,FORMAT(cs.EndDate, 'dd/MM/yyyy') AS 'End Date'
,a.AcademyName
,r.RoomName
,t.FirstName + ' ' + t.LastName AS 'Trainer'
,s.FirstName + ' ' + s.LastName AS 'Student'
FROM CourseScheduleAttendees csa
INNER JOIN CourseScheduleTrainers cst
ON csa.TrainerID = cst.TrainerID
INNER JOIN Employees t
ON cst.EmployeeID = t.EmployeeID
AND t.EmployeeType = 'T'
INNER JOIN Employees s
ON csa.AttendeeID = s.EmployeeID
AND s.EmployeeType = 'S'
INNER JOIN CourseCatalog cc
ON csa.CourseCatalogID = cc.CourseCatalogID
INNER JOIN CourseSchedule cs
ON cc.CourseScheduleID = cs.CourseScheduleID
INNER JOIN Rooms r
ON cs.RoomsID = r.RoomsID
INNER JOIN Academies a
ON r.AcademyID = a.AcademyID;

How to query multiple weak tables using a join

I have a database with two strong entities, and three weak entities. The weak entities only have foreign key references to the primary key of the strong tables they related to, to create an association between the tables.
I have a query selecting from one table the way I want, but am not sure how to go about selecting from all three tables at once and displaying the data in one query.
ERD:
I have tried many different joins and can not get them to work properly. This select displays the information that I want for one table:
select f.FilmName, concat(p.FirstName, ' ', p.LastName) as Producer
from filmtable as f
inner join persontable as p
inner join produced;
I would like to be able to select and display all the information from all three weak tables, in a format similar to:
FilmName, Producer, ScreenWriter, Director.
You need:
select f.FilmName, concat(ppr.FirstName, ' ', ppr.LastName) as Producer,
concat(psw.FirstName, ' ', psw.LastName) as ScreenWriter,
concat(pdir.FirstName, ' ', pdir.LastName) as Director
from filmtable as f
left join produced as prod ON prod.FilmID = f.FilmID
left join Directed as dir ON dir.FilmID = f.FilmID
left join ScreenWote as sw ON sw.FilmID = f.FilmID
left join persontable as ppr ON prod.PersonID = ppr.personID
left join persontable as psw ON sw.PersonID = psw.personID
left join persontable as pdir ON dir.PersonID = pdir.personID;
Alternate solution is to use sub queries in SELECT statement to achieve all 3 parties i.e. Producer, Writer and Director, in one row.
SELECT f.FilmName,
(
SELECT concat(p.FirstName, ' ', p.LastName)
FROM persontable AS pt
JOIN produced AS a
ON pt.PersonID = a.PersonID
WHERE p.FilmID = f.FilmID
) AS producer,
(
SELECT concat(p.FirstName, ' ', p.LastName)
FROM persontable AS pt
JOIN screenwrote AS a
ON pt.PersonID = a.PersonID
WHERE p.FilmID = f.FilmID
) AS ScreenWriter,
(
SELECT concat(p.FirstName, ' ', p.LastName)
FROM persontable AS pt
JOIN directed AS a
ON pt.PersonID = a.PersonID
WHERE p.FilmID = f.FilmID
) AS Director
FROM filmtable AS f

SQL - Get the names instead of ID

I have a table called tbl_appointment which has 2 foreign keys: idclient and idemployee which they are referencing tbl_persons.
So what i want to do is instead of getting the id of idclient and idemployee, i want to get the names (name,last_name,last_sname) which they belong to those id.
Query
SELECT CONCAT(tbl_persons.name,' ',tbl_persons.last_name,' ',tbl_persons.last_sname) as fullname, tbl_appointment.*
FROM tbl_appointment
INNER JOIN tbl_persons ON tbl_persons.idpersons = tbl_appointment.idemployee
INNER JOIN tbl_persons ON tbl_persons.idpersons = tbl_appointment.idclient
WHERE idclient= '$user';
You can use the following query, using a LEFT JOIN instead of INNER JOIN:
SELECT
CONCAT(p1.name, ' ', p1.last_name, ' ', p1.last_sname) AS client_fullname,
CONCAT(p2.name, ' ', p2.last_name, ' ', p2.last_sname) AS employee_fullname
FROM tbl_appointment ta
LEFT JOIN tbl_persons p1 ON ta.idclient = p1.idpersons
LEFT JOIN tbl_persons p2 ON ta.idemployee = p2.idpersons
WHERE ta.idclient = '$user'
Try the following
SELECT
app.*,
CONCAT(client.name,' ',client.last_name,' ',client.last_sname) AS client_full_name,
CONCAT(empl.name,' ',empl.last_name,' ',empl.last_sname) AS empl_full_name
FROM tbl_appointment app
LEFT JOIN tbl_persons client ON app.idclient=client.id
LEFT JOIN tbl_persons empl ON app.idemployee=empl.id
WHERE app.idclient= '$user'
Try the following code: Only thing is you have to select the clients and employees separately, together is more difficult
SELECT name,last_name,last_sname
FROM tbl_persons WHERE id IN (
SELECT DISTINCT idclient FROM tbl_appointment;
); -- This will select all the clients
SELECT name,last_name,last_sname
FROM tbl_persons WHERE id IN (
SELECT DISTINCT idemployee FROM tbl_appointment;
); -- This will select all the employees

Mysql triple join error:Not unique table/alias: 'cushbu_mark_user_favorites'

I have 3 tables in my db
1)cushbu_users (id,first_name,last_name)
2)cushbu_art (id,user_id(FK cushbu_user),title,base_price etc...) -for store user arts
3)cushbu_mark_user_favorites (id,user_id(FK cushbu_user),art_id(FK cushbu_art)) -for marking favourite items
I want to fetch the all art items of a particular user favourited
with count of favourites each art (stored in cushbu_mark_usier_favorites table )
Here is my query
SELECT
cushbu_art.id AS art_id,
cushbu_art.title,
cushbu_art.base_price,
cushbu_art.image_name,
CONCAT(
cushbu_users.first_name,
' ',
cushbu_users.last_name
) AS artist_name,COUNT(cushbu_mark_user_favorites.art_id)
FROM
cushbu_art
JOIN cushbu_mark_user_favorites ON cushbu_mark_user_favorites.art_id = cushbu_art.id
JOIN cushbu_users ON cushbu_users.id = cushbu_art.artist_id
LEFT JOIN cushbu_mark_user_favorites ON cushbu_art.id=cushbu_mark_user_favorites.art_id
WHERE
cushbu_mark_user_favorites.user_id = 68
But i got Not unique table/alias: 'cushbu_mark_user_favorites' this join statement
LEFT JOIN cushbu_mark_user_favorites ON cushbu_art.id=cushbu_mark_user_favorites.art_id
UPDATE
SELECT
a.id AS art_id,
a.title,
a.base_price,
a.image_name,
CONCAT(
c.first_name,
' ',
c.last_name
) AS artist_name,COUNT(b.art_id)
FROM
cushbu_art a
JOIN cushbu_mark_user_favorites b ON b.art_id = a.id
JOIN cushbu_users c ON c.id = a.artist_id
LEFT JOIN b ON a.id=b.art_id
WHERE
b.user_id = 68
Try below query.
SELECT
cushbu_art.id AS art_id,
cushbu_art.title,
cushbu_art.image_name,
CONCAT(
cushbu_users.first_name,
' ',
cushbu_users.last_name
) AS artist_name , b.favorites_count as total_fav
FROM
cushbu_mark_user_favorites
LEFT JOIN cushbu_art ON cushbu_art.id=cushbu_mark_user_favorites.art_id
LEFT JOIN cushbu_users ON cushbu_users.id = cushbu_art.artist_id
LEFT JOIN (SELECT art_id,count(*) as favorites_count FROM cushbu_mark_user_favorites GROUP BY art_id) as b ON b.art_id=cushbu_art.id
WHERE cushbu_mark_user_favorites.user_id=1
GROUP BY cushbu_art.id
Hope this will helpful to you.

How to get all records from one table and irrespective of where clause

Below is my Query, when I am putting where clause, my recordset get reduced. I can understand why it reducing,
But I am looking for all records from teacher_profiles table (31 records) and then corresponding details if there is any else blank.
Can any one suggest ? Using mySQL
SELECT
CONCAT(a.teacherFirstName , ' ', COALESCE(a.teacherMiddleName, ''), ' ', a.teacherLastName ) as teacherName ,
COALESCE(GROUP_CONCAT(DISTINCT c.subjectLongName SEPARATOR ', ') , '') AS subjects ,
COALESCE(GROUP_CONCAT(DISTINCT f.classStd SEPARATOR ', ') , '') AS classes ,
FROM
teacher_profiles a **<--- this table has 31 records. I need all these 31** Record in recordset
LEFT JOIN subjectteacherallocation b ON a.teacherId = b.teacherId
LEFT JOIN subject_master c ON b.subjectId = c.subjectId
LEFT JOIN timetabledistribution d ON a.teacherId = d.teacherId
LEFT JOIN TimeTableClassSection e ON d.TimeTableClassSectionId = d.TimeTableClassSectionId
LEFT JOIN class_master f ON f.classId = e.classId
WHERE b.academicYear='2015' <--- condition reducing record
GROUP BY a.teacherId