I got this, and I want to get their "company" names for each one.
SELECT `client`.`name`,`client`.`lastname`
FROM `check`,`reserv`,`client`
WHERE `check`.`idReserv`=`reserv`.`id`
AND `reserv`.`idPerson`=`client`.`id`
ORDER BY `check`.`id`
, and I want to get their "company" names for each one, from table "company".
So I tried this:
SELECT `client`.`name`,`client`.`lastname`, `company`.`name`
FROM `check`,`reserv`,`client`,`company`
WHERE `reserv`.`idCompany`=`company`.`id`
AND `check`.`idReserv`=`reserv`.`id`
AND `reserv`.`idPerson`=`client`.`id`
ORDER BY `check`.`id`
but there is some people in the table "reserv" with an "idCompany" inexistent. so with that condition, this query only show me people who has an existent "id" in the table "company". I want to show the people with no company up and the space of company.name in blank if there is no company
I tryed many ways even with joins, but I cannot fix it. I'm tired to write "company" also.
You can use LEFT JOIN for this purpose like-
reserv r LEFT JOIN company c ON r.idCompany = c.id
You should use LEFT join instead.
SQL LEFT JOIN
SELECT c.name, c.lastname, co.name
FROM check AS ck
LEFT JOIN reserv AS r ON(ck.idReserv = r.id)
LEFT JOIN client AS c ON(r.idPerson = c.id)
LEFT JOIN company AS co ON(r.idCompany = co.id)
ORDER BY c.id
The ANSI 89 standard uses , notation for table joins with the criteria of the join being in the where clause. However I don't believe mySQL supports this outer style of join needed to address your problem. To express an outer join in this syntax you would need to use a *= for left join or =* for a right join; but again not sure mySQL supports it.
So in your case:
SELECT `client`.`name`,`client`.`lastname`, `company`.`name`
FROM `check`,`reserv`,`client`,`company`
WHERE `reserv`.`idCompany`*=`company`.`id`
AND `check`.`idReserv`=`reserv`.`id`
AND `reserv`.`idPerson`=`client`.`id`
ORDER BY `check`.`id`
However, I find that notation difficult to read and no need for all the escaping of table/column names (except reserved words)... so the below follows the ANSI 92 standards which allow for the use of INNER and LEFT Join syntax to explicitly define the type of join. Both notations should optimize to the same execution plan so either works (provided mySQL supports the *= notation) as well; it's just a matter of which standard you choose to use.
SELECT client.name
, client.lastname
, company.name
FROM `check`
INNER JOIN reserv
on `check`.idReserv=reserv.id
INNER JOIN client
on reserv.idPerson=client.id
LEFT JOIN company
on reserv.idCompany=company.id
ORDER BY `check`.id
Related
I'm trying to study SQL.
I have a problem with JOIN
I want to display ref_id, pro_name, class_name but I couldn't.
I find EFFICIENT solution.
MY QUERY (DOESN'T WORK)
SELECT
ref_id, pro_name, class_name
FROM
RC, RP, PP, LP
WHERE
RC.ref_id = RP.ref_id
Avoid using commas be CROSS JOIN
You could use JOIN to instead of commas
like this.
SELECT
RP.ref_id, PP.pro_name, LP.class_name
FROM
RP
LEFT JOIN RC ON RC.ref_id = RP.ref_id
LEFT JOIN PP ON PP.pro_id = RP.pro_id
LEFT JOIN LP ON LP.lec_id = RP.lec_id
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax.
You would seem to want:
select rp.pro_id, pp.pro_name, lp.class_name
from rp left join
pp
on rp.pro_id = pp.pro_id left join
lp
on rp.lec_id = lp.lec_id;
Note the use of left join. This ensure that all rows are in the result set, even when one or the other joins doesn't find a matching record.
From what I can see, the table rc is not needed to answer this specific question.
I am having some problems with this homework question:
I have been able to successfully complete almost all of the query except for the "Only include states with at least 3 diamond mines". I would like to ask how I can add this part to the query.
select I.state, sum(P.capacity)
from Infrastructure I
natural join Mine M
join produces P
on P.mine = M.entryno
join Commodity C
on C.comID = P.commodity
where C.name like '%Diamond%'
group by I.state
If your attempt works fine other than condition mentioned in question following query should work:
select I.state, sum(P.capacity)
from Infrastructure I
natural join Mine M
join produces P
on P.mine = M.entryno
join Commodity C
on C.comID = P.commodity
where C.name like '%Diamond%'
group by I.state
having count(P.mine) >=3;
It will count the no. of commodity for each state as you already has group by on State.
Hope it helps!
Use a HAVING clause to count and assert the number of diamond mines:
SELECT
I.state,
SUM(P.capacity)
FROM Infrastructure I
NATURAL JOIN Mine M
INNER JOIN produces P
ON P.mine = M.entryno
INNER JOIN Commodity C
ON C.comID = P.commodity
WHERE
C.name LIKE '%Diamond%'
GROUP BY
I.state
HAVING
COUNT(*) >= 3;
Note: Natural join seems error prone to me and could break at some point. The best thing to use are explicit joins.
I've been trying to write some code in SQL, but it keeps coming up with a syntax error regarding the join, and I can't work out why.
SELECT `COUNTRY$`.country_name, `PARTNER$`.partner_name, count(member_id)
FROM `Member$`
Left Join `COUNTRY$`
ON `MEMBER$`.country_id=`COUNTRY$`.country_id
lEFT jOIN `PARTNER$`
on `MEMBER$`.partner_ID = `PARTNER$`.partner_ID
Group By country_name,Partner_name
Any help would be appreciated.
May have something to do with how your table names are in 'thisFormat$'. Also you did not specify which table member_id was coming and group by also doesn't specify which table country_name, partner_name was from.
Try putting aliases on the tablenames and see if that eliminates the problem
SELECT c.country_name, p.partner_name, count(m.member_id)
FROM `Member$` m
left join `COUNTRY$` c on c.country_id = m.country_id
left join `PARTNER$` p on p.partner_id = m.partner_id
GROUP BY c.country_name, p.partner_name
When I use right join I get the same results as using left join or just join. Can anyone show me where I have gone wrong?
I have 3 tables as follows:
langugages
id
code eg "hu","en"
language_default
id
text
language_translations
id
lang_id (FK the id of the language in the languages table)
default_lang_id (FK the id of the text in the languages_default table)
text (the translation)
When I execute the following query, I expect to get all of the hungarian translations from the language_translations table and all of the text fields from the language_default table with a null value where there is no hungarian translation.
SELECT `language_translations`.`text`
, `language_default`.`text`
FROM `languages`
, `language_translations`
RIGHT JOIN `language_default` ON `language_default`.`id` = `language_translations`.`default_lang_id`
WHERE `languages`.`code` = 'hu'
AND `languages`.`id` = `language_translations`.`lang_id`
Instead I only get text from the language_default table where there are translations for that text in the tranlsation table. I would expect that behaviour from a left join or normal join but not a right join. Any ideas why I am not getting all of the entries from the langugage_defailt table?
First of all you are using combination of normal join and rights join in wrong way. You can use as per below query.
2nd thing right join means you will get all record from right side and corresponding records from left side and if left side does not have corresponding record then it will show NULL.
Left join is its reverse.
Normal join or comma join will provide only common rows.
So if your tables only have common rows then all joins will provide same results.
SELECT
`language_translations`.`text` , `language_default`.`text`
FROM `languages` AS l
JOIN `language_translations` AS t
ON l.`id` = t.`lang_id` AND l.`code` = 'hu'
RIGHT JOIN `language_default` AS d
ON d.`id` = t.`default_lang_id`;
Don't mix implicit joins and explicit joins. A simple rule is: don't use , in the from clause. The following restructures your query to use left outer join:
SELECT `language_translations`.`text`, ld.`text`
FROM language_default ld left outer join
language_translations lt
on ld.`id` = lt.`default_lang_id` left outer join
`languages` l
on l.`id` = lt.`lang_id` and l.`code` = 'hu' ;
When using outer joins, you need to be very careful about where additional conditions go. Conditions on the driving table (the first a left outer join, the last for a right outer join) can go in the where clause. For other tables, the conditions should go in the on clause. Otherwise, they turn the outer join into an inner for the simple reason that (almost) any comparison to NULL is equivalent to false.
I have this query:
SELECT hit.timestamp,hit.id,config.Name,hit.meter_id,levels.LevelName, pos.sm_pos , hit.hit_value
FROM pos,hit,controllers,levels,config
WHERE hit.id=config.id
AND hit.meter_id=levels.id
AND pos.id=hit.id
AND pos.controller_id=controllers.id;
How to make an inner join query from this? With aliases or something? I was looking and I can't find anything for multiple table query.
The way you are joining tables is outdated now. It was used eartlier, now we use keyword like INNER/NATURAL/LEFT OUTER/RIGHT OUTER/CROSS etc. to join tables on basis of requirement.
Refer Join in Mysql
SELECT hit.timestamp,
hit.id,
config.Name,
hit.meter_id,
levels.LevelName,
pos.sm_pos,
hit.hit_value
FROM hit
INNER JOIN config
ON hit.id = config.id
INNER JOIN levels
ON hit.meter_id = levels.id
INNER JOIN POS
ON pos.id = hit.id
INNER JOIN controllers
ON pos.controller_id = controllers.id;
Note : The query posted by you is according the SQL-89 standard and the second posted by me is according to SQL-92.
The SQL-92 standard introduced INNER JOIN .. ON and OUTER JOIN .. ON in order to replace the more complex(?) syntax of SQL-89.
If you want to reformat your query, you can do it like this:
SELECT
H.timestamp,
H.id,
F.Name,
H.meter_id,
L.LevelName,
P.sm_pos,
H.hit_value
FROM pos AS P
INNER JOIN controllers AS C ON P.controller_id = C.id
INNER JOIN hit AS H ON P.id = H.id
INNER JOIN levels AS L ON H.meter_id = L.id
INNER JOIN config AS F ON H.id =F.id;
Notice that I've taken the liberty to add aliases on your table names, this can simplify your queries alot.
To understand how joins work in MySQL, read about it here in the manual. A good tutorial about joins was written by Jeff Atwood, you can find it here.