Mysql join for the following ER - php

I have the following table structure of my db:
tbl_project
tbl_employee
tbl_deliverable
user_to_deliverable
Where tbl_prjct and tbl_deliverable have a 1-to-many relationship,
tbl_employee and tbl_deliverable have many-many relationships so they are split into user_to_deliverable table.
I want a query to show project_name(from tbl_project), project's deliverables (from tbl_deliverable) and employee name which that specific deliverable is assigned to.
Can I get help writing this query?

Your desired query is much like 89.67% like this :D
SELECT a.ProjectName,
b.deliverables,
d.employeename
FROM tbl_project a
INNER JOIN tbl_deliverable b
ON a.projectID = b.projectID
INNER JOIN user_to_deliverable c
ON b.recordID = c.RecordID
-- or could be the primary key
INNER JOIN tbl_employee d
ON c.userID = d.userID

Approximate solution without knowing your schema. If you want the deliverables/employees concatenated for each project it would probably be best done by retrieving the results and parsing in a non-SQL language (PHP, Python, or whatever you are using). If you want this completely done in SQL you will need to use GROUP_CONCAT().
select tbl_project.name as project,
tbl_deliverable.name as deliverable,
tbl_employee.name as employee
from tbl_project
join tbl_deliverable
on (tbl_project.id = tbl_deliverable.project_id)
join user_to_deliverable
on (tbl_deliverable.id = user_to_deliverable.deliverable_id)
join tbl_employee
on (user_to_deliverable.employee_id = tbl_employee.id)

Related

How to join hierarchical table in MySQL (table joins other table that joins other table that joins other table)?

I have 3 tables, tb_item, tb_branch, tb_department, tb_division.
As you can see:
tb_division is under tb_department
tb_department is under branch
tb_branch has no superior
for example if I want to retrieve item_id 1 or 2 or 3 then this should be the result
If I want to retrieve item_id 2 then it will show the department and branch.
My problem is that I can nested join them if if I know the item is related to a specific table but in this case since tb_item can be related to tb_division or tb_department and tb_branch I don't know what query should I formulate.
Changing the database design is not an option since this design is already implemented.
SELECT column-names
FROM table-name1 JOIN table-name2
ON column-name1 = column-name2
WHERE condition
Never Mind guys. I managed to solved it myself. been struggling since I thought I need to do tons of subqueries. Thanks for the answers tho.
SELECT
i.item_id,
dv.division_name,
COALESCE(dept.department_name, dept2.department_name) AS department_name,
COALESCE(br.branch_name, br2.branch_name, br3.branch_name) AS branch_name
FROM
tb_item AS i
LEFT JOIN
tb_division AS dv
ON i.division_id = dv.division_id
LEFT JOIN
tb_department AS dept2
ON dv.department_id = dept2.department_id
LEFT JOIN
tb_branch AS br2
ON dept2.branch_id = br2.branch_id
LEFT JOIN
tb_department AS dept
ON i.department_id = dept.department_id
LEFT JOIN
tb_branch AS br3
ON dept.branch_id = br3.branch_id
LEFT JOIN
tb_branch AS br
ON i.branch_id = br.branch_id

Dynamically created sql not happy

I have a table which contains records of a 'widget' many of the columns contain just the Id of a record in a different table. When editing the widget record users are allowed to do a save even if it is incomplete. They can open it later and continue.
The problem I have, is when it is incomplete my query returns nothing because the where clause contain fields which have default 0 in them and there is no match in the other tables. Here is a sample of script which illustrates this problem.
select Client,Make,Model,Shape
from
widget,clients,makes,models,shapes
where
widget.ClientId = '3' and
widget.MakeId = makes.Id and
widget.ModelId = models.Id and
widget.ShapeId = shapes.Id
I am building this query dynamically using PHP so am trying to keep it as simple as possible. All sugestions welcome, thanks.
The problem is that you are using an implicit inner join (implicit meaning that you do the join in the where clause). Inner joins return matching records only, therefore if some of the data are incomplete, no records will be returned.
Use an outer join instead, that return all records from one of the tables in the join and the matching records from the other table (MySQL does not support full outer join, but this is not relevant here anyway).
Based on your description widget table is your main table, so use left join to join all other tables on widget to get the widget even if it is incomplete:
select c.Client, m.make, md.model, s.shape
from widget w
left join clients c on c.id = w.ClientId
left join makes m on m.id = w.MakeId
left join models md on md.id = w.ModelId
left join shapes s on s.id = w.ShapeId
select c.Client, m.make, md.model, s.shape
from widget w
join clients c on c.id = w.ClientId
join makes m on m.id = w.MakeId
join models md on md.id = w.ModelId
join shapes s on s.id = w.ShapeId
Use Joins instead of multiple tables in FROM Clause.
Instead of direct join use LEFT JOIN so that no matter if there is records from other tables, still first table entries will be returned:
SELECT Client, Make, Model, Shape
FROM widget
LEFT JOIN clients ON widget.ClientId = widget.Id
LEFT JOIN makes ON widget.MakeId = makes.Id
LEFT JOIN models ON widget.ModelId = models.Id
LEFT JOIN shapes ON widget.ShapeId = shapes.Id
WHERE widget.ClientId = 3
Table columns should be in lower case
Table names should be in singular form, e.g. model, shape
Foreign keys should be in other table. Instead of widget having ModelId, model should have widget id
I may be wrong if relations are different

Get information from another table using intermediate table

Here I have three tables authors, books_has_authors and books.
Books_has_author is an intermediate table which contains only the primary keys form other two tables. I am trying to write an sql query which will return me all the books name written by a particular author. I am new to relational database concepts as well as writing queries for relational databases. I know some join queries but I'm really confused how to use them for fetching information through an intermediate table. Any help will be appreciated ! :)
You only need to add an additional JOIN, like this:
SELECT b.book_id, b.book_name, a.author_id, a.author_name
FROM books b
JOIN books_has_author ba ON ba.books_book_id = b.book_id
JOIN author a ON ba.author_author_id = a.author_id
WHERE a.author_id = xxx
Try this:
SELECT b.* FROM books b
INNER JOIN books_has_author bha
ON bha.books_book_id = b.book_id
WHERE bha.author_author_id = "$$YOUR AUTHOR ID"
use JOIN like that :-
SELECT *
FROM books
JOIN books_has_author ON books_has_author.books_book_id = books.book_id
JOIN author ON books_has_author.author_author_id = author.author_id
WHERE author.author_id = '123'

How can I create a MySQL query to include all of this information?

I am creating a report and I need to be able to create a query(s) to pull the information below into a report. Essentially here's what I want listed:
ship.name
personnel.first_name
personnel.last_name
crew_position_title.title
personnel_next_of_kin.next_of_kin_relation
personnel_next_of_kin.next_of_kin_first_name
personnel_next_of_kin.next_of_kin_last_name
personnel_next_of_kin.next_of_kin_telephone
personnel_next_of_kin.next_of_kin_alt_telephone
personnel_next_of_kin.other_kin_relation
personnel_next_of_kin.other_kin_first_name
personnel_next_of_kin.other_kind_last_name
personnel_next_of_kin.other_kin_telephone
personnel_next_of_kin.other_kin_alt_telephone
The only condition would be WHERE personnel.currently_serving_ship_id IS NOT NULL on the personnel table.
How would I go about creating a query to give me the data I need? I have tried using JOIN but I don't have much experience with them.
Below is the ERD of the tables I need data from with fields of interest highlighted:
How about something like?
SELECT s.name, p.first_name, p.last_name, c.title, pnk.next_of_kin_relation,
pnk.next_of_kin_first_name, pnk.next_of_kin_last_name, pnk.next_of_kin_telephone,
pnk.next_of_kin_alt_telephone, pnk.other_kin_relation, pnk.other_kin_first_name,
pnk.other_kin_last_name, pnk.other_kin_telephone, pnk.other_kin_alt_telephone
FROM personnel p
LEFT JOIN personnel_next_of_kin pnk ON pnk.personnel_id = p.personnel_id
LEFT JOIN ship s ON s.ship_id = p.currently_serving_ship_id
LEFT JOIN personnel_key_info pk ON pk.personnel_id = p.personnel_id
LEFT JOIN crew_position_title c ON c.crew_pos_id = p.personnel_id
WHERE p.currently_serving_ship_id IS NOT NULL
This is the long version of the query. I am not really sure about this: LEFT JOIN crew_position_title c ON c.crew_pos_id = p.personnel_id. I can't tell what key should be used there, can't figure out using the naming convention.
Query was not tested but you can give it a shot and fix the syntax issue if there are any.

Screwy MySQL Code Logic

The default_albums table is used for storing album data.
The default_hottest_categories table is used to store the category
data
The default_album_hc_connect table is used to connect the default_hottest_categories table with the default_albums
table.
I need to be able to display all albums that are apart of the category which is_hottest. the is_hottest column is located in the default_hottest_categories table. The below code is what I have so far:
$q1 = $this->db->query("SELECT * FROM default_albums a, default_hottest_categories d INNER JOIN default_album_hc_connect dc
ON d.id = dc.hottest_categories_id INNER JOIN default_albums ON dc.albums_id = default_albums.album_id
WHERE d.is_hottest = 'Yes'");
I really do not know if this is correct or not. So if you can help me, I'd much appreciate it.
This should work. You had an extra instance of the default_albums table in your FROM clause. I removed that. Also you generally want to join all your tables together. The comma you had in there is used for CROSS JOINS, but is not used that often and is not needed in this case. Also I would recommend only taking the fields you need in your SELECT clause.
SELECT *
FROM default_albums a
INNER JOIN default_album_hc_connect dc
ON a.albums_id = dc.album_id
INNER JOIN default_hottest_categories d
ON dc.hottest_categories_id = d.id
WHERE d.is_hottest = 'Yes'"

Categories