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
Related
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
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.
I have an instrument list and teachers instrument list.
I would like to get a full instrument list with id and name.
Then check the teachers_instrument table for their instruments and if a specific teacher has the instrument add NULL or 1 value in a new column.
I can then take this to loop over some instrument checkboxes in Codeigniter, it just seems to make more sense to pull the data as I need it from the DB but am struggling to write the query.
teaching_instrument_list
- id
- instrument_name
teachers_instruments
- id
- teacher_id
- teacher_instrument_id
SELECT
a.instrument,
a.id
FROM
teaching_instrument_list a
LEFT JOIN
(
SELECT teachers_instruments.teacher_instrument_id
FROM teachers_instruments
WHERE teacher_id = 170
) b ON a.id = b.teacher_instrument_id
my query would look like this:
instrument name id value
--------------- -- -----
woodwinds 1 if the teacher has this instrument, set 1
brass 2 0
strings 3 1
One possible approach:
SELECT i.instrument_name, COUNT(ti.teacher_id) AS used_by
FROM teaching_instrument_list AS i
LEFT JOIN teachers_instruments AS ti
ON ti.teacher_instrument_id = i.id
GROUP BY ti.teacher_instrument_id
ORDER BY i.id;
Here's SQL Fiddle (tables' naming is a bit different).
Explanation: with LEFT JOIN on instrument_id we'll get as many teacher_id values for each instrument as teachers using it are - or just a single NULL value, if none uses it. The next step is to use GROUP BY and COUNT() to, well, group the result set by instruments and count their users (excluding NULL-valued rows).
If what you want is to show all the instruments and some flag showing whether or now a teacher uses it, you need another LEFT JOIN:
SELECT i.instrument_name, NOT ISNULL(teacher_id) AS in_use
FROM teaching_instrument_list AS i
LEFT JOIN teachers_instruments AS ti
ON ti.teacher_instrument_id = i.id
AND ti.teacher_id = :teacher_id;
Demo.
Well this can be achieved like this
SELECT
id,
instrument_name,
if(ti.teacher_instrument_id IS NULL,0,1) as `Value`
from teaching_instrument_list as til
LEFT JOIN teachers_instruments as ti
on ti.teacher_instrument_id = til.id
Add a column and check for teacher_instrument_id. If found set Value to 1 else 0.
I've been working on a project that until now has only needed to find 1 row from the joined table. But now I need to grab multiple rows..
So as it stand my sql works something like:
Select rows for each company for this particular project which alone would find company details (name, id, telephone.. blah).
Then I join a table that contains form data submitted for each company (multiple forms - so multiple records)
Until now i have been specifying one formid to look for in the join, but now i need to specify multiple ones.
If I use WHERE form_id = 1 OR form_id = 2 OR form_id = 3 ... I get a result of only the first form match that is found per company..
If I mix up the query so it looks for the forms 1st and returns multiple records for each company with different form data - that works in this sense..
But I am then looping through this array in a view and creating a table row per record (previously each row was a new company) but using the latter would cause multiple records to show for the same company.
Any way I can do this? I tried group by with the latter method but this results in only 1 record again.
SELECT DISTINCT p.project_company_has_user_id, p.project_company_has_user_project_id, p.project_company_has_user_user_id, c.company_id, c.company_hall_no, c.company_company_name, c.company_type, c.company_country, c.company_stand_number, c.company_image_file_1, p2.project_id, p2.project_name, u.user_id, u.user_username, o.orders_id, o2.order_detail_id, o2.order_detail_product_id, f2.form_question_has_answer_id, f2.form_question_has_answer_request, f2.form_question_has_answer_form_id, f2.form_question_has_answer_user_id
FROM project_company_has_user p
INNER JOIN company c ON p.project_company_has_user_company_id = c.company_id
INNER JOIN project p2 ON p.project_company_has_user_project_id = p2.project_id
INNER JOIN user u ON p.project_company_has_user_user_id = u.user_id
INNER JOIN form f ON p.project_company_has_user_project_id = f.form_project_id
LEFT JOIN orders o ON p.project_company_has_user_user_id = o.orders_user_id
LEFT JOIN order_detail o2 ON ((o2.order_detail_orders_id = o.orders_id AND (o2.order_detail_product_id = 65 OR o2.order_detail_product_id = 68 OR o2.order_detail_product_id = 64)))
LEFT JOIN form_question_has_answer f2 ON ((f2.form_question_has_answer_form_id = 297 AND f2.form_question_has_answer_user_id = p.project_company_has_user_user_id))
WHERE (f.form_template_name = "custom" AND p.project_company_has_user_garbage_collection = 0 AND p.project_company_has_user_project_id = 48) AND (LCASE(c.company_country) LIKE "%uk%" OR LCASE(c.company_country) LIKE "%uk%") ORDER BY company_company_name asc
you need another field in order_detail as o2 . this field is row_index(position),etc for positioning record
LEFT JOIN order_detail o2 ON (o2.row_index=1 AND (o2.order_detail_orders_id = o.orders_id AND (o2.order_detail_product_id = 65 OR o2.order_detail_product_id = 68 OR o2.order_detail_product_id = 64)))
Personally I would use an Outer Join for the table of which elements you need to list all matches. Should you them need to clean up that data you can build the logic into the Join Condition (as step 2). Depending on the volume of data you are handling and whether or not you need to reuse it later in the same proc, you may want to post that primary dataset into a temp table and use that as source (primary) for your later logic.
Hope that helps. If you need the code, let me know, but it is pretty straight forward.
Regards
Mac
Still returns the same results! Got rid of divs. Now the query is:
SELECT w.windate,
w.wintime,
w.field,
w.htname,
w.vtname,
w.plateumpire,
w.fieldumpire1,
w.fieldumpire2,
w.fieldumpire3,
p.pteamname,
p.teamcoach
FROM playerteams AS p
INNER JOIN sportsdb_wins AS w ON p.pteamname IN (w.htname,w.vtname)
WHERE p.teamcoach = '$coachid'
AND p.forteam = '$teamid'
but no joy!
I am trying to display a list of teams that all have the same p.teamcoach. The playerteams table contains each team and has teamcoach set to that coach. sportsdb_wins contains a list of scheduled games that I want to display for a given coach.
How are you associating team coaches to teams. I would suggest you have a table for coaches and foreign key this to the playerteams table. That way your coaches are only entered once. Something like...
SELECT w.windate,
w.wintime,
w.field,
w.htname,
w.vtname,
w.plateumpire,
p.pteamname,
pc.coach_name
FROM player_coaches AS pc
INNER JOIN playerteams AS p
ON p.coachId = pc.coachId
INNER JOIN sportsdb_wins AS w
ON p.pteamname IN (w.htname, w.vtname)
WHERE p.coachId = '$coachId'
AND p.forteam = '$teamId'