Join in 3 tables - php

I have 3 tables food,restaurant and categories.
I want to make join between these. I have a query to join food and categories as:
> $Category = DB::table('food')->select('food.Food_id','food.FoodName','food.FoodImage','food.FoodType','categories.CategoryName')->join('categories','categories.Category_id','=','food.Category_id')->where('categories.CategoryName', '=','Breakfast')->get();
I want to join restaurant with this. How I can do that?
My tables are:
food:
Food_id(PK)
FoodName
Category_id(FK)
And category table is:
Category_id(PK)
CategoryName
And restaurant table is:
Res_id
Res_Name
Address_loc
Food_id(FK)

$Category = DB::table('food')->select('food.Food_id','food.FoodName','food.FoodImage','food.FoodType','categories.CategoryName', 'restaurant.Res_Name')
->join('restaurant', 'restaurant.Food_id', '=', 'food.Food_id')
->join('categories','categories.Category_id','=','food.Category_id')
->where('categories.CategoryName', '=','Breakfast')->get();
You can use Food_id to join the restaurant onto food.
(Not sure if the syntax of the code is correct, but it fits to your example. Might have to change the tablename of restaurant as you seem to be switching between lower and upper case)

Related

join 2 tables through additional one MySQL/PHP

Let's say we have 2 tables
#film_info
[
movieID
movieValue1
movieValue2
]
#actor_info
[
actorID
actorValue1
actorValue2
]
and we also have
#film_actor
[movieID, actorID]
what i'm trying to do is to join those movie and actro via movie_actor, so that i can select a movie and see every actor, that stars in it.
$db->prepare("SELECT *
FROM film_info fi
INNER JOIN film_actor fa
ON fi.film_id = fa.film_id
INNER JOIN actor_info ai
ON fa.actor_id = ai.actor_id");
with something like this. It works, but gets me an array of all the film information for every actor thats stars in it. For example, if there's six actors it will return 6 arrays of same movie info, only having different [actor_name] every time.
Which stands a question: Is there any way to make it return one array with a list of all the actors? Or should i just write a function to manually pick all the actors from 6+ arrays?
Sorry for my terrible english and thanks in advance!
You should group by the movie, then group_concat the actors so they are all returned in the 1 movie row. You also can use using for the on when the columns of both tables have the same name. This should do what you are asking:
SELECT fi.movie_title, group_concat(actor_name_column)
FROM film_info fi
INNER JOIN film_actor using(film_id)
INNER JOIN actor_info using(actor_id)
group by film_id

query for similar results (LIKE %..%) on values that are associated with a different table

I have three TABLES in MySQL:
items, category and intermediate (to allow 'many-to-many' relationships).
TABLE category: TABLE items:
id_category theme id_items part
1 dog 1 tomato
2 fruit 2 rottweiler
3 bird 3 blackbird
4 veg 4 apple
TABLE intermediate:
id_intermediate id_category id_items
1 1 2
2 2 4
3 3 3
4 4 1
There are thousands of entries in each of the tables category and items but 'only' hundreds in the 'relationship' table - intermediate.
now, what I want to do is to query for a certain value, a variable using LIKE '%$var' to check for similar results (spelled word) but only on the COLUMN part in the TABLE items, that have associations or that exist in the TABLE intermediate.
I know how to do the query on the TABLE items (use PHP):
$query = "SELECT * FROM items WHERE part LIKE '%$var%' LIMIT 10";
but as I mentioned, I need only those that have association with the other TABLE category.
I've tried many things, includeding a nested query like:
$query = "SELECT * FROM
(SELECT items.part, items.id_items, id_intermediate, id_items
FROM items JOIN intermediate
WHERE inter.id_items IS NOT NULL)
WHERE items.part LIKE '%$var%'";
but I got this error:"Invalid query: Every derived table must have its own alias", which I don't really understand.
In any case, does any one here know how to solve my problem?
I couldn't find such a question in this forum.
UPDATE (solution):
scaisEdge provided the solution.
$query =
SELECT items.part, items.id_items, inter.id_intermediate, inter.id_items
FROM items
JOIN intermediate on inter.id_items
JOIN category on inter.id_category = category.id AND inter.id_items = items.id_items
WHERE items.part LIKE concat ('%', '$var' , '%') ";
I believe this isn't a duplicate because the other proposals refer to the ALIAS error, which was part of my false attempt. But even with solving the alias error, it had to go through a different approach.
for a specific category (eg:dog ) you could use a join on the 3 tables
and for the filter you could use a cooncat for build the right like string
$query =
SELECT items.part, items.id_items, inter.id_intermediate, inter.id_items
FROM items
JOIN intermediate inter on inter.id_items
JOIN category on inter.id_category = category.id and category.name = 'dog'
WHERE items.part LIKE concat ('%', '$var' , '%') ";
for all the categories you can avoid the 3th join
$query = "
SELECT items.part, items.id_items, inter.id_intermediate, inter.id_items
FROM items
JOIN intermediate inter on inter.id_items
WHERE items.part LIKE concat ('%', '$var' , '%') ";
$query = "SELECT i.* FROM
(SELECT items.part, items.id_items, id_intermediate, id_items
FROM items JOIN intermediate
WHERE inter.id_items IS NOT NULL) as i
WHERE i.items.part LIKE '%$var%'";
This should fix your problem.
"as i" is an alias

Inner Join with PHP

I checked through a few different questions previously asked but they were more advanced than what I need at the moment. I need a simple way to join two tables and display the results so that I can then manipulate them in any way I want once it is collecting the data the way I need it to. The code below is very simple... Yet I am having trouble. First I create a class that connects to the database then I created a method to query the database and join to tables based on common columns. After that I would like the loop to go through the top four results based on their title name which are 'gold', 'silver', 'platinum', 'palladium' I just want to make sure that the join request is working. Please view the code below and maybe you can tell me why the results I keep getting are
1 Gold
1 Gold
1 Gold
1 Gold
Literally I get Gold 4 times when I need a list of all 4 precious metals.I thought that when the while loop runs through I would get each one as it is supposed to run through all 4 rows and there are no more yet it runs through the same 1st row and brings back 1 Gold every time. Both the id and the metals title name. If I am missing something please feel free to ask and I will add it for you if it helps.
class testJoin{
public function __construct($dbCon){
$this->dbConnection = $dbCon;
}
function testingJoin($dbCon) {
if($results = $this->dbConnection->query("SELECT metal.id, metal.title, price.metalId FROM metal INNER JOIN price ON metal.id = price.metalId ORDER BY metal.title LIMIT 0,4")){
while($data = $results->fetch_assoc()){
printf("<p style=\"display:inline;\">%s</p>
<p style=\"display:inline;\">%s</p><br />", $data['id'], $data['title']);
}
}
$dbCon->close();
}
}
JOIN creates a cross-product of the matching rows in the two tables. If there are multiple price rows for each metal, you'll get all those different prices, and then you take the first 4 rows of this.
If you want to limit the number of metals, but not the total number of rows, you can join with a subquery:
SELECT metal.id, metal.title, price.metalId
FROM (SELECT id, title
FROM metal
ORDER BY title
LIMIT 4) AS metal
JOIN price ON metal.id = price.metalId
Or if you want to get just one row per metal, you can use GROUP BY
SELECT metal.id, metal.title, price.metalId
FROM metal
JOIN price ON metal.id = price.metalId
GROUP BY metal.id
ORDER BY metal.title
LIMIT 4
Here you have no reason to join to prices table at all
SELECT metal.id, metal.title
FROM metal
ORDER BY metal.title
Cos u added to result nothing from there.
If u really need join to prices and display results by "not repeated" metal names, u should just GROUP results
SELECT metal.id, metal.title
FROM metal
INNER JOIN price ON (metal.id = price.metalId)
GROUP BY metal.id
ORDER BY metal.title
After that you can retrieve some useful data from prices table, for example average price for each metal
SELECT metal.id, metal.title, AVG(price.price) AS metal_price
FROM metal
INNER JOIN price ON (metal.id = price.metalId)
GROUP BY metal.id
ORDER BY metal.title
Also you should understand difference between LEFT JOIN and INNER JOIN.
LEFT - will fetch ALL needed rows from first table (metal) and add results from second (prices) even if there is no such metal in prices table (then results from second table will be NULL). (metal.id = price.metalId) can be understanded as "ALL metals with some prices, if they have"
INNER - will fetch ONLY those rows from first table which are presented in second table, by "JOIN ON" condition. (metal.id = price.metalId) can be understanded as "THOSE metals WHICH HAVE prices"
https://pp.vk.me/c623725/v623725696/14ae4/459rNGJwMJc.jpg

Selecting data from a table based on conditions with other tables

I'm really unsure how best to go about writing this query. I have 3 tables and I need to run a query pulling data from one, based on conditions in the others.
Tables: surveys, survey_countries, survey_categories
surveys:
id | survey_id | network_id
survey_countries:
id | survey_id | network_id | country
survey_categories:
id | survey_id | network_id | category
(The survey_id in survey_countries and survey_categories relates to the survey_id column in the surveys table as opposed to the id column).
I need to retrieve data from surveys for a specific country and a specific category. Then I need to be able to UNION for other categories, but I guess I can do that later. My attempt:
SELECT surveys.*
FROM survey_countries
LEFT JOIN surveys ON survey_countries.survey_id = surveys.survey_id ANd survey_countries.network_id = surveys.network_id
LEFT JOIN survey_categories ON survey_countries.survey_id = surveys.survey_id AND survey_categories.network_id = surveys.network_id
WHERE survey_countries.country = 'GB'
AND survey_categories.category = 'my_category'
GROUP BY surveys.id
Thanks!
EDIT: the following seems to work:
SELECT s.*, ca.category, co.country
FROM surveys s
LEFT JOIN survey_countries co ON s.survey_id = co.survey_id AND s.network_id = co.network_id
LEFT JOIN survey_categories ca ON s.survey_id = ca.survey_id AND s.network_id = ca.network_id
WHERE ca.category = 'uncategorised'
AND co.country = 'GB';
I'm just not sure it's the best way to do it since I need to grab surveys with multiple categories later on?
Without example data and an example output, helping you on this query is very difficult. However..... your 2nd join relates survey_countries with surveys. I think you mean to join it to the survey_categories. Also, you have a Group By, with no aggregate functions. Get rid of it until you have too much information an need to summarize columns
I am not saying this is correct, but it is slightly more 'correct' than yours
SELECT surveys.*
FROM survey_countries
LEFT JOIN surveys
ON survey_countries.survey_id = surveys.survey_id
AND survey_countries.network_id = surveys.network_id
LEFT JOIN survey_categories
ON survey_categories.survey_id = surveys.survey_id
AND survey_categories.network_id = surveys.network_id
WHERE survey_countries.country = 'GB'
AND survey_categories.category = 'my_category'
(If you can, load up a schema and sample data in sqlfiddle. It will make this problem easier to solve.)

how to get column names from 2 different table id

I have two tables and joined them to one different table
1 table named 'rec_dept'
id_dept
id_divisi
nama_dept
2 table named 'rec_divisi'
id_divisi
nama_div
3 joined table named 'rec_divdep'
id_divdep
id_divisi
id_dept
How to get nama_dept where in the same id_divisi?
Maybe you're looking for this:
SELECT `nama_dept` FROM `rec_dept` WHERE `id_divisi` IN (SELECT `id_divisi` FROM `rec_divdep`);
Hope that helps
you can do a SELECT query with a LEFT JOIN function to get data
SELECT a.`nama_dept` FROM `rec_dept` a
LEFT JOIN `rec_divisi` b
ON a.`id_divisi` = b.`id_divisi`
ORDER BY a.`id_divisi` ASC
SELECT documentation
LEFT JOIN documentation
select a.id_dept, a.id_divisi, a.nama_dept, b.id_divisi, b.nama_div, c.id_divdep, c.id_divisi from rec_divdep as c left join rec_divisi as b on (c.id_divisi = b.id_divisi) left join rec_dept as a on (c.id_divisi = a.id_divisi)
what database do you use. I code mine as mysql, basically I condition the three tables that has same id_divisi. I did not test it but I am pretty sure of the logic based on what I understand.

Categories