开发者

How would I join this query in one single SQL statement?

Let's say I have these tables, with these fields:

companies: company_id | name | num_employees

companies_countries: company_id | country_id

countries: country_id | country_iso_code

Assuming this is a 1:1 relationship: How can I join the country_iso_code directly into the compa开发者_JAVA技巧ny recordset, when I fetch all the companies? I think I would need two joins here?


A simple example :

select c.name, n.country_iso_code
from companies c,
companies_countries x,
countries n
where x.company_id = c.company_id
and n.country_id = x.country_id

Edit

For a good intro to JOIN, have a look at SQL JOIN.


SELECT 
    companies.company_id, 
    companies.name, 
    companies.num_employees, 
    countries.country_iso_code
FROM
    companies
LEFT JOIN
    companies_countries ON (companies_countries.company_id = companies.company_id)
LEFT JOIN
    countries ON (countries.country_id = companies_countries.country_id);

A query that uses a LEFT JOIN instead of an INNER JOIN or an implicit join, will return companies even when they have no country assigned. On the other hand, a query with an INNER JOIN would skip companies that do not have an assigned country in companies_countries.

Note that your design is implying that each company can be assigned more than one country. If you want to enforce only one country for each company, simply put a country_id column in your companies table. You would not need the companies_countries table.


select name, country_iso_code 
from companies left join companies_countries 
   on (companies.company_id = companies_countries.company_id)
left join countries 
   on (companies_countries.country_id = countries.country_id)


SELECT co.*, cu.country_iso_code 
FROM companies co 
LEFT JOIN companies_countries cc ON cc.company_id = co.company_id
LEFT JOIN countries c ON c.country_id = cc.country_id

Why LEFT JOIN and not the WHERE condition like in other examples? A join table (companies_countries) is not typically used in 1:1 relationships - it is overnormalization.

When your relationship ceases to be 1:1:

SELECT co.*, GROUP_CONCAT(cu.country_iso_code)
FROM companies co 
LEFT JOIN companies_countries cc ON cc.company_id = co.company_id
LEFT JOIN countries c ON c.country_id = cc.country_id

This will return results like

CompanyA | Canada,USA,Mexico
CompanyB | Ireland,UK,Japan


This is not a 1:1 relationship. A country can have more the one company.

This is either a 1:N relationship (for some reason implemented using two relational tables), or the M:N relationship which describes multinational companies.

If this is a 1:N relationship, you could just put the country_code field into the companies table, in which case one join would be enough:

SELECT  *
FROM    companies co
LEFT JOIN
        countries cn
ON      cn.country_code = co.country_code

Your design is viable for both 1:N and M:N relationships, in which case two joins are required:

SELECT  co.*, cn.*
FROM    companies co
LEFT JOIN
        company_countries cc
ON      cc.company_id = co.company_id
LEFT JOIN
        countries cn
ON      cn.country_code = cc.country_code

If this is a 1:N relationship, you should make company_id a PRIMARY KEY in the company_country table.

If this is a M:N relationship, you should make a composite PRIMARY KEY on company_country (company_id, country_code)

You may want to read this article in my blog about the difference between entity-relationship model and its relational implementation:

  • What is entity-relationship model?


Yes, you would need two joins.

You can create a view and fake a single join though...


select companies.* from countries, companies_countries, companies where countries.country_id=companies_countries and companies_countries.company_id=company_id and countries.country_iso_code='xxxx'

where xxxx is the iso code you want to match


select c.company_id, c.name, c.num_employees, co.county_iso_code from
companies c, companies_countries cc, countries co
where c.company_id = cc.company_id 
and cc.country_id = co.country_id
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜