mysql joining to many tables while including a main table - php

I'm having trouble because the main table doesn't have the foreign key i'm trying to search by. Rather, the secondary tables have the key I'm searching by. This means I have to build my information in an array, table by table, joining each with the main table to find the data.
transactions is the main table. deposits is joined to transactions, then I get the deposit info from transactions table. same is then done for payments, invoices, etc. It seems like a less-than-ideal way to design it, or maybe i'm missing something.
i am hoping there is a better way to join the tables in one shot rather than joining them all with union joins.
so currently i say
select * from transactions T left join deposits D on T.id = D.tID where D.account = '123'
union
select * from transactions T left join invoices I on T.id = I.tID where I.account = '123'
union....
etc
any better suggestions? thanks!

i think this should do the work
select * from transactions T
left join deposits D on T.id = D.tID and D.account = '123'
left join invoices I on T.id = I.tID and I.account = '123'
.....

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

Multiple table JOIN Row count

Ok, I have a slightly complicated MySQL query
SELECT
childcare_attendance.supplier_id,
suppliers.name As `Childcare Provider`,
Count(families.ufi) As Attended,
families.ufi
FROM
childcare_attendance
LEFT OUTER JOIN
suppliers ON suppliers.id = childcare_attendance.supplier_id
LEFT OUTER JOIN
clients ON childcare_attendance.client_id = clients.id
LEFT OUTER JOIN
families ON clients.family_id = families.id
WHERE
childcare_attendance.trashed <> 1
GROUP BY
childcare_attendance.supplier_id, families.ufi
My issue is I want to create a report that lists the number of unique families that are attending each of the childcare places. I assumed that the above query would perform the task, although the childcare providers are showing multiple times and I am unsure why.
EDIT
Here is a SQL Fiddle without data (I will work on getting some test data in there)
http://sqlfiddle.com/#!9/7ef8e8

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'

mysql join three tables order by third

I have a query
SELECT jss_products.* from jss_products_tree,jss_products
WHERE stock!=0 AND
jss_products.productID = jss_products_tree.productID
and sectionID=1 order by price
Which returns me a big array with products. Now I need to join 3rd table jss_extrafields_values,
which has productID and content fields, and somehow order the array by the content from 3rd table. Also it might have more than one rows with different content but same product.ID.. any ideas on how to join all of them? I tried a lot of tutorials but none of them helped me.. thanks
Its easier to use join over from table1, table2 as its better to read. And you can just join the 3th table.
SELECT jss_products.* from jss_products_tree
INNER JOIN jss_products
ON jss_products.productID = jss_products_tree.productID
INNER JOIN jss_extrafields_values
on jss_extrafields_values.productId = jss_products.productID
WHERE stock!=0 AND
and sectionID=1
order by jss_extrafields_values.field

Categories