12.2.7.1. JOIN Syntax

download 12.2.7.1. JOIN Syntax

of 15

Transcript of 12.2.7.1. JOIN Syntax

  • 8/14/2019 12.2.7.1. JOIN Syntax

    1/15

    12.2.7.1. JOIN Syntax

    MySQL supports the following JOIN syntaxes for the table_references part ofSELECT

    statements and multiple-tableDELETEandUPDATEstatements:

    table_references:table_reference, table_reference

    | table_reference [INNER | CROSS] JOIN table_reference[join_condition]

    | table_reference STRAIGHT_JOIN table_reference

    | table_reference {LEFT|RIGHT} [OUTER] JOIN table_referencejoin_condition

    | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_reference

    | { OJ table_reference LEFT OUTER JOIN table_referenceON conditional_expr}

    table_reference:

    tbl_name [[AS] alias] [index_hint)]| table_subquery[AS] alias

    join_condition:

    ON conditional_expr

    | USING (column_list)

    index_hint:USE {INDEX|KEY} (index_list)]

    | IGNORE {INDEX|KEY} (index_list)]| FORCE {INDEX|KEY} (index_list)]

    index_list:index_name [, index_name] ...

    Index hints can be specified to affect how the MySQL optimizer makes use of indexes. Formore information, seeSection 12.2.7.2, Index Hint Syntax.

    Note that several changes in join processing were made in MySQL 5.0.12 to make MySQLmore compliant with standard SQL. These changes include the ability to handle nested joins(including outer joins) according to the standard. If a nested join returns results that are notwhat you expect, please consider upgrading to MySQL 5.0. Further details about thechanges in join processing can be found atJOIN Syntax.

    You should generally not have any conditions in the ON part that are used to restrict which

    rows you want in the result set, but rather specify these conditions in theWHERE clause.

    There are exceptions to this rule.

    Note that INNER JOIN syntax allows a join_condition only from MySQL 3.23.17 on.

    The same is true forJOIN and CROSS JOIN only as of MySQL 4.0.11.

    http://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/delete.htmlhttp://dev.mysql.com/doc/refman/4.1/en/delete.htmlhttp://dev.mysql.com/doc/refman/4.1/en/delete.htmlhttp://dev.mysql.com/doc/refman/4.1/en/update.htmlhttp://dev.mysql.com/doc/refman/4.1/en/update.htmlhttp://dev.mysql.com/doc/refman/4.1/en/update.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/5.0/en/join.htmlhttp://dev.mysql.com/doc/refman/5.0/en/join.htmlhttp://dev.mysql.com/doc/refman/5.0/en/join.htmlhttp://dev.mysql.com/doc/refman/5.0/en/join.htmlhttp://dev.mysql.com/doc/refman/5.0/en/join.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/4.1/en/update.htmlhttp://dev.mysql.com/doc/refman/4.1/en/delete.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.html
  • 8/14/2019 12.2.7.1. JOIN Syntax

    2/15

    A table reference can be aliased using tbl_name AS alias_name ortbl_namealias_name:

    SELECT t1.name, t2.salary FROM employee AS t1, info AS t2

    WHERE t1.name = t2.name;

    SELECT t1.name, t2.salary FROM employee t1, info t2

    WHERE t1.name = t2.name; A table_subqueryis also known as a subquery in the FROMclause. Such

    subqueries must include an alias to give the subquery result a table name. A trivialexample follows; see alsoSection 12.2.8.8, Subqueries in the FROMclause.

    SELECT * FROM (SELECT 1, 2, 3) AS t1;

    The conditional_exprused with ON is any conditional expression of the form thatcan be used in aWHERE clause.

    If there is no matching row for the right table in the ON orUSING part in a LEFTJOIN, a row with all columns set toNULL is used for the right table. You can use thisfact to find rows in a table that have no counterpart in another table:

    SELECT left_tbl.*

    FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id

    WHERE right_tbl.id IS NULL;

    This example finds all rows in left_tbl with an idvalue that is not present inright_tbl (that is, all rows in left_tbl with no corresponding row in right_tbl).This assumes that right_tbl.idis declaredNOT NULL. SeeSection 7.2.7, LEFTJOIN and RIGHT JOINOptimization.

    The USING(column_list) clause names a list of columns that must exist in bothtables. The following two clauses are semantically identical:

    a LEFT JOIN b USING (c1,c2,c3)

    a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3

    TheNATURAL [LEFT] JOIN of two tables is defined to be semantically equivalentto an INNER JOIN or a LEFT JOIN with a USING clause that names all columns thatexist in both tables.

    INNER JOIN and , (comma) are semantically equivalent in the absence of a joincondition: both produce a Cartesian product between the specified tables (that is,each and every row in the first table is joined to each and every row in the secondtable).

    RIGHT JOIN works analogously to LEFT JOIN. To keep code portable acrossdatabases, it is recommended that you use LEFT JOIN instead ofRIGHT JOIN.

    The { OJ ... LEFT OUTER JOIN ...} syntax shown in the preceding list existsonly for compatibility with ODBC. The curly braces in the syntax should be writtenliterally; they are not metasyntax as used elsewhere in syntax descriptions.

    SELECT left_tbl.*

    FROM { OJ left_tbl LEFT OUTER JOIN right_tbl ON left_tbl.id =right_tbl.id }

    WHERE right_tbl.id IS NULL;

    STRAIGHT_JOIN is similar to JOIN, except that the left table is always read beforethe right table. This can be used for those (few) cases for which the join optimizerputs the tables in the wrong order.

    http://dev.mysql.com/doc/refman/4.1/en/unnamed-views.htmlhttp://dev.mysql.com/doc/refman/4.1/en/unnamed-views.htmlhttp://dev.mysql.com/doc/refman/4.1/en/unnamed-views.htmlhttp://dev.mysql.com/doc/refman/4.1/en/unnamed-views.htmlhttp://dev.mysql.com/doc/refman/4.1/en/unnamed-views.htmlhttp://dev.mysql.com/doc/refman/4.1/en/unnamed-views.htmlhttp://dev.mysql.com/doc/refman/4.1/en/unnamed-views.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/left-join-optimization.htmlhttp://dev.mysql.com/doc/refman/4.1/en/unnamed-views.html
  • 8/14/2019 12.2.7.1. JOIN Syntax

    3/15

    Some join examples:

    SELECT * FROM table1,table2 WHERE table1.id=table2.id;

    SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id;

    SELECT * FROM table1 LEFT JOIN table2 USING (id);

    SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id

    LEFT JOIN table3 ON table2.id=table3.id;

    Previous/Next/Up/Table of Contents

    User Comments

    Posted by Scott Atkins on January 23 2003 6:43am [Delete][Edit]

    Tip time:

    (Background: This database is used to keep track of scores for students in my classes.)

    So in this case, I have three tables, one has student's "codename" (as posting their real name onthe web is a no-no) and an index (there is more data in this table, but this is all you really need toknow.) Then there's a table with the assignments, containing the assignment name, and an indexfor each assignment. Finally, there is a scores table, which has for each paper I get turned in, astudent_id (releated to the student index) an act_id (related to the assignments index) and a score.

    It looked something like this:students table:

    +----+---------------+| id | codename |

    +----+---------------+| 1 | Budy |+----+---------------+

    assignments table:+--------+------------+| act_id | name |

    +--------+------------+| 1 | Activity 1 || 2 | Activity 2 |

    +--------+------------+

    scores table:+------------+--------+-------+

    | student_id | act_id | score |+------------+--------+-------+

    http://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index.htmlhttp://dev.mysql.com/doc/mysql/comment.php?id=1641&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=1641&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=1641&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=1641http://dev.mysql.com/doc/mysql/comment.php?id=1641http://dev.mysql.com/doc/mysql/comment.php?id=1641http://dev.mysql.com/doc/mysql/comment.php?id=1641http://dev.mysql.com/doc/mysql/comment.php?id=1641&action=deletehttp://dev.mysql.com/doc/refman/4.1/en/index.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.htmlhttp://dev.mysql.com/doc/refman/4.1/en/index-hints.htmlhttp://dev.mysql.com/doc/refman/4.1/en/select.html
  • 8/14/2019 12.2.7.1. JOIN Syntax

    4/15

    | 1 | 1 | 10 |

    | 1 | 2 | 10 |

    +------------+--------+-------+

    Now the problem was, I wanted to have the assignments listed across the top, and the scores nextto the names. Something like this:

    +---------------+------------+------------+-------+| codename | Activity 1 | Activity 2 | Total |+---------------+------------+------------+-------+| budy | 10 | 10 | 20 |

    +---------------+------------+------------+-------+

    So here's how the sql statement ended up:SELECT names.codename,s1.score AS "Score1", s1.comment AS "Comments1",s2.score AS "Score2", s2.comment AS "Comments2",SUM(st.score) AS "Total"FROM students names

    LEFT JOIN scores s1 ON s1.act_id=1 AND names.id=s1.student_idLEFT JOIN scores s2 ON s2.act_id=2 AND names.id=s2.student_idLEFT JOIN scores st ON names.id=st.student_idWHERE names.codename ''GROUP BY names.codenameORDER BY names.codename;

    As you can see, for each activity, I need to add another left join, but it looks exactly like the lastone, thus it is easy to build through a program like php. I hope this helps someone out.

    Posted by Thomas Mayer on April 21 2003 6:58pm [Delete][Edit]

    I use left joins to generate sums on one table using different conditions:t1 to make sure that ALL grouped records are shownt(n+1) for use per conditionand as mentioned above, the JOIN condition must be used as well for the primary key AND forthe condtion per sum!

    Here is an example:

    drop table if exists testtable;create table testtable(mykey int not null,

    mygroup int,cond int,value int,primary key (mykey));

    insert into testtablevalues (1, 1, 1, 5), (2, 1, 1, 6), (3, 1, 2, 3), (4, 2, 2, 4), (5, 3, 3, 5);

    http://dev.mysql.com/doc/mysql/comment.php?id=2341&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=2341&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=2341&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=2341http://dev.mysql.com/doc/mysql/comment.php?id=2341http://dev.mysql.com/doc/mysql/comment.php?id=2341http://dev.mysql.com/doc/mysql/comment.php?id=2341http://dev.mysql.com/doc/mysql/comment.php?id=2341&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    5/15

    -- returns nothingselect t1.mygroup, sum(t2.value) as cond_1, sum(t3.value) as cond_2, sum(t4.value) as cond_3from testtable t1left join testtable t2 on t1.mykey=t2.mykeyleft join testtable t3 on t1.mykey=t3.mykey

    left join testtable t4 on t1.mykey=t4.mykeywhere t2.cond=1and t3.cond=2and t4.cond=3group by 1order by 1;

    -- returns correct sumsselect t1.mygroup, sum(t2.value) as cond_1, sum(t3.value) as cond_2, sum(t4.value) as cond_3from testtable t1left join testtable t2 on t1.mykey=t2.mykey and t2.cond=1

    left join testtable t3 on t1.mykey=t3.mykey and t3.cond=2left join testtable t4 on t1.mykey=t4.mykey and t4.cond=3group by 1order by 1;

    mygroup | cond_1 | cond_2 | cond_31 | 11 | 3 | 02 | 0 | 4 | 03 | 0 | 0 | 5

    Posted by joerg schaber on June 11 2003 2:24am [Delete][Edit]

    I also think that the missing feature of FULL OUTER JOIN is a real drawback to MySQL.However, from MySQL 4 on you can use a workaround using the UNION construct. E.g. athttp://www.oreillynet.com/pub/a/network/2002/04/23/fulljoin.html

    Posted by Y G on October 27 2003 3:52am [Delete][Edit]

    Below is an example of how to left-join multiple tables independently.

    SELECT ...FROM table 1

    LEFT JOIN table 2 on (table1.id = table2.id)LEFT JOIN table 3 on (table1.id2 = table3.id2)LEFT JOIN table 4 on (table1.id3 = table4.id3)

    Posted by name withheld on November 13 2003 1:33pm [Delete][Edit]

    Martin,your comment & others helped emensely!

    http://dev.mysql.com/doc/mysql/comment.php?id=2809&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=2809&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=2809&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=2809http://dev.mysql.com/doc/mysql/comment.php?id=2809http://dev.mysql.com/doc/mysql/comment.php?id=2809http://www.oreillynet.com/pub/a/network/2002/04/23/fulljoin.htmlhttp://www.oreillynet.com/pub/a/network/2002/04/23/fulljoin.htmlhttp://dev.mysql.com/doc/mysql/comment.php?id=3526&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3526&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3526&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3526http://dev.mysql.com/doc/mysql/comment.php?id=3526http://dev.mysql.com/doc/mysql/comment.php?id=3526http://dev.mysql.com/doc/mysql/comment.php?id=3610&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3610&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3610&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3610http://dev.mysql.com/doc/mysql/comment.php?id=3610http://dev.mysql.com/doc/mysql/comment.php?id=3610http://dev.mysql.com/doc/mysql/comment.php?id=3610http://dev.mysql.com/doc/mysql/comment.php?id=3610&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3526http://dev.mysql.com/doc/mysql/comment.php?id=3526&action=deletehttp://www.oreillynet.com/pub/a/network/2002/04/23/fulljoin.htmlhttp://dev.mysql.com/doc/mysql/comment.php?id=2809http://dev.mysql.com/doc/mysql/comment.php?id=2809&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    6/15

    Here's a left-join select that also has a regular join to another table.I want to get all Plans (& associated SubType info),but also see which plans user 13 is signed upfor, but only if the expire_date hasn't passed.This select will show all Plan & SubType info,

    but user-info only if the user is signed up,and the expire-date hasn't passed.

    SELECT*FROM mt_SubTypes, mt_Plans as t1LEFT JOIN mt_UserPlans as t2on (t1.id_plan = t2.id_planand t2.expire_date > '2003-11-12'and t2.id_user = 13)WHERE

    t1.id_subType = mt_SubTypes.id_subType;

    Posted by Cory McHugh on December 22 2003 2:54pm [Delete][Edit]

    This is an example of using a left to get lookup values from a table twice. The reason that anouter join was used instead of an inner join, was that in this case, there may be values that arenull inside of the degree table.

    SELECT d.degDegId, m1.majDescription AS major_1, m2.majDescription AS major_2FROM degree AS dLEFT OUTER JOIN major AS m1

    ON d.degMajor1 = m1.majMajIdLEFT OUTER JOIN major AS m2ON d.degMajor2 = m2.majMajId

    Posted by Joonas Kekoni on August 19 2004 6:37am [Delete][Edit]

    The oracle outter join syntax:select a1.a,a1.b,a2.a,a2.b from a1,a2 where a1.a=a2.b(+);

    Is expressed like:select a1.a,a1.b,a2.a,a2.b from a1 left join a2 on a2.b=a1.a where 1=1;

    NOTE: a2 is the optional table:

    (PLEASE NOTE you must NOT specify a2 in from line(!!).The 1=1 is optional,but I added it here so you could see where to add other conditions).

    full example:

    http://dev.mysql.com/doc/mysql/comment.php?id=3767&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3767&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3767&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3767http://dev.mysql.com/doc/mysql/comment.php?id=3767http://dev.mysql.com/doc/mysql/comment.php?id=3767http://dev.mysql.com/doc/mysql/comment.php?id=4848&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=4848&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=4848&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=4848http://dev.mysql.com/doc/mysql/comment.php?id=4848http://dev.mysql.com/doc/mysql/comment.php?id=4848http://dev.mysql.com/doc/mysql/comment.php?id=4848http://dev.mysql.com/doc/mysql/comment.php?id=4848&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=3767http://dev.mysql.com/doc/mysql/comment.php?id=3767&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    7/15

    drop table a1; drop table a2;create table a1 (a integer,b integer);create table a2 (a integer,b integer);insert into a1 (a,b) values (1,2);insert into a1 (a,b) values (3,5);

    insert into a2 (a,b) values (2,1);insert into a2 (a,b) values (3,5);select a1.a,a1.b,a2.a,a2.b from a1 left join a2 on a2.b=a1.a where 1=1;drop table a1; drop table a2;

    PS.I prefer the Oracle syntax and would like to see it supported by MySql too.

    Posted by Fred Mitchell on December 11 2004 1:47pm [Delete][Edit]

    Let's say you are doing a LEFT JOIN with a table that shares a column name in common with

    another table, and that you are selecting for instances where the join is missing, that is IS NULL.

    Normally, the common column name is "wiped out" by the null record, but here is a workaroundfor it: You simply alias that common column name in the select. For instance,

    CREATE TABLE t1 (INT id NOT NULL, ....);CREATE TABLE t2 (INT id NOT NULL, ....);...SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.idWHERE t2.id IS NULL;

    would result in the column 'id' being null on each selected row. Instead, you can do:

    SELECT *, t1.id AS id FROM t1 LEFT JOIN t2 ON t1.id = t2.idWHERE t2.id IS NULL;

    And now the 'id' column will be preserved since the alias is evaluated *after* the LEFT JOIN.

    Posted by [name withheld] on December 14 2004 12:08pm [Delete][Edit]

    Note that table_reference in the above grammar may also be a "anonymous table" resulting froma join, as shown below. I don't know if this is intended or by occasion, but for me it works

    (MySQL 4.0.22):

    SELECT products.idFROM productsLEFT OUTER JOIN (author2productsINNER JOIN author ON author.id = author2products.authorid) ON products.id = author2products.productsid

    http://dev.mysql.com/doc/mysql/comment.php?id=5413&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=5413&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=5413&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=5413http://dev.mysql.com/doc/mysql/comment.php?id=5413http://dev.mysql.com/doc/mysql/comment.php?id=5413http://dev.mysql.com/doc/mysql/comment.php?id=5423&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=5423&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=5423&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=5423http://dev.mysql.com/doc/mysql/comment.php?id=5423http://dev.mysql.com/doc/mysql/comment.php?id=5423http://dev.mysql.com/doc/mysql/comment.php?id=5423http://dev.mysql.com/doc/mysql/comment.php?id=5423&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=5413http://dev.mysql.com/doc/mysql/comment.php?id=5413&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    8/15

    This enables you to OUTER JOIN with the results of an INNER JOIN within one query.

    Posted by Ben Griffin on June 30 2005 11:23am [Delete][Edit]

    Scenario: A group of companies have a set of publications. Any company in the group cansubscribe to any number of publications.Requirement: Create a query to generate a list of companies, showing the count of publicationsand subscriptions for each company.

    create table company ( cid int not null, cref char(64) not null,primary key (cid));create table publication ( pid int not null, pcid int not null, pref char(64) not null,primary key(pid));create table subscription ( scid int not null,spid int not null,primary key (scid,spid));

    insert into company values (1,'A Corp');

    insert into company values (2,'B Corp');insert into company values (3,'C Corp');insert into company values (4,'D Corp');insert into company values (5,'E Corp');

    insert into publication values (10,1,'A News');insert into publication values (11,1,'A Digest');insert into publication values (12,1,'A Review');insert into publication values (20,2,'B News');insert into publication values (51,5,'E Digest');insert into publication values (52,5,'E Review');

    insert into subscription values (1,10);insert into subscription values (1,11);insert into subscription values (1,20);insert into subscription values (1,51);insert into subscription values (1,52);insert into subscription values (2,10);insert into subscription values (4,10);insert into subscription values (4,52);

    select cref,count(distinct pid) as pubs,count(distinct spid) as subs from company left join

    publication on cid=pcid left join subscription on cid=scid group by cid order by cref;+--------+------+------+

    | cref | pubs | subs |+--------+------+------+| A Corp | 3 | 5 |

    | B Corp | 1 | 1 || C Corp | 0 | 0 |

    | D Corp | 0 | 2 |

    http://dev.mysql.com/doc/mysql/comment.php?id=6248&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=6248&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=6248&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=6248http://dev.mysql.com/doc/mysql/comment.php?id=6248http://dev.mysql.com/doc/mysql/comment.php?id=6248http://dev.mysql.com/doc/mysql/comment.php?id=6248http://dev.mysql.com/doc/mysql/comment.php?id=6248&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    9/15

    | E Corp | 2 | 0 |

    +--------+------+------+

    Posted by Mike Nix on August 24 2005 4:11am [Delete][Edit]

    This checks for an event that should happen yearly, depending on other factors - it could beapplied to checking for any event that should occur at regular intervals - ie monthly or weekly -with adjustments to the code for selecting max_calves.

    This is a fairly complex example, with lots of joins, aliases and grouping... Its aim is to extract alist of cows which have not calved every year in a given period. It accounts for cows which havenot been in the database for the entire period, are not currently on our property(locations.local==1), or which are too young to have calves for the entire period (they can't calvebefore 2 years old).There are many actions that signal entry/exit of an animal - eg birth/buy/sell/death. many (ornone) of them may be recorded in the history table. As a fallback, animal.yob is the year of birthof the animal.Cows and their calves are all stored as "animals" in the animals table (the mob field distinguishesbetween them).

    The query returns the number of calves they did have in the time frame (num_calves) and thenumber of calves they should have had (max_calves).

    Tables: (columns not relevant to query have been removed)create table history (id int(10), date datetime, action int(2) not null, info text, primarykey(id,date));create table actions (id int(2) auto_increment primary key, name char(20), type char(20));create table mob_types (id int(2) primary key, name char(20));create table locations (id int(2) auto_increment primary key, name char(20), alive tinyint(1),local tinyint(1));create table animals (id int(10) auto_increment primary key, yob int(4), tag1 char(10), motherint(10), mob int(2), location int(2));

    Foreign keys:animals.id locations.idanimals.mob -> mobs.idmobs.type -> mob_types.idhistory.action -> actions.id

    The SQL to make it happen:The original formatting is easier to read, but the leading spaces are not preserved here (the sitewon't let me use html to get it either)$xxx are the input variables:$start_year, $end_year: date range to check (inclusive)$all_animals: 0= alive and on property, 1= everything$nomiss: 0= those that missed a year, 1=those that didn't miss

    http://dev.mysql.com/doc/mysql/comment.php?id=6468&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=6468&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=6468&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=6468http://dev.mysql.com/doc/mysql/comment.php?id=6468http://dev.mysql.com/doc/mysql/comment.php?id=6468http://dev.mysql.com/doc/mysql/comment.php?id=6468http://dev.mysql.com/doc/mysql/comment.php?id=6468&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    10/15

    $allow_miss: number of misses considered acceptable.

    select a1.*,aquire.date,disposal.date,count(a2.id) num_calves,(IF(IsNull(disposal.date),$end_year,

    IF(DATE_FORMAT(disposal.date,'%Y') $start_year,IF(DATE_FORMAT(aquire.date,'%Y')>(a1.yob+2),DATE_FORMAT(aquire.date,'%Y'),a1.yob+2),IF(a1.yob>($start_year-2),a1.yob+2,$start_year))+1) as max_calvesfrom animals as a1left join animals as a2on a1.id=a2.mother

    and a2.yob>=$start_yearleft join history as aquireon a1.id=aquire.idand aquire.action in (select id from actions where type='aquire')left join history as disposalon a1.id=disposal.idand disposal.action in (select id from actions where type='disposal')where a1.mob in (select id from mobs where mobtype in (select id from mob_types wherename='Cow'))and (($all_animals>0)or a1.location in (select id from locations where alive=1 and local=1))group by a1.idhaving IF($nomiss>0, num_calves>=(max_calves-$allow_miss), num_calves

  • 8/14/2019 12.2.7.1. JOIN Syntax

    11/15

    Posted by Odimar Tomazeli on January 19 2006 7:13pm [Delete][Edit]

    Here a example join 3 tables like that

    s_g_a_t

    ............|

    ............+-> s_c

    .....................|

    .....................+-> s_t_i

    SELECT distinct sc.TType, si.IdFROM s_g_a_t st LEFT JOIN s_c sc ON(st.GA = sc.GA and sc.id_app = 'XXX' and sc.Select =1) INNER JOIN s_t_i si ON (sc.TType = si.DL)Order by si.Id

    Posted by [name withheld] on June 15 2006 8:36pm [Delete][Edit]

    This is an example for joining tables which are related by 2 fields.

    Squeme:

    tblA(idA, idB1, idB2)tblB(idB, Name)relations: tblA.idB1->tblB.IdBtblB.idB2->tblB.IdB

    and we want to obtain all records of tblA with its related tblB.Name

    The sql statment could be like this:

    SELECTtblA.IdA,tblB.Name AS Name1,tblB_1.Name AS Name2FROMtblA INNER JOINtblB tblB_1 ON tblA.IdB1 = tblB_1.IdBINNER JOIN tblB

    ON tblA.IdB2 = tblB.IdB

    (tested in MySql v4.0.24)

    Posted by barbarina on September 12 2006 2:17pm [Delete][Edit]

    You can emulate FULL OUTER JOIN using UNION (from MySQL 4.0.0 on):

    http://dev.mysql.com/doc/mysql/comment.php?id=7116&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7116&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7116&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7116http://dev.mysql.com/doc/mysql/comment.php?id=7116http://dev.mysql.com/doc/mysql/comment.php?id=7116http://dev.mysql.com/doc/mysql/comment.php?id=7708&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7708&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7708&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7708http://dev.mysql.com/doc/mysql/comment.php?id=7708http://dev.mysql.com/doc/mysql/comment.php?id=7708http://dev.mysql.com/doc/mysql/comment.php?id=7990&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7990&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7990&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7990http://dev.mysql.com/doc/mysql/comment.php?id=7990http://dev.mysql.com/doc/mysql/comment.php?id=7990http://dev.mysql.com/doc/mysql/comment.php?id=7990http://dev.mysql.com/doc/mysql/comment.php?id=7990&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7708http://dev.mysql.com/doc/mysql/comment.php?id=7708&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=7116http://dev.mysql.com/doc/mysql/comment.php?id=7116&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    12/15

    with two tables t1, t2:

    SELECT * FROM t1LEFT JOIN t2 ON t1.id = t2.id

    UNIONSELECT * FROM t1RIGHT JOIN t2 ON t1.id = t2.id

    with three tables t1, t2, t3:

    SELECT * FROM t1LEFT JOIN t2 ON t1.id = t2.idLEFT JOIN t3 ON t2.id = t3.idUNION

    SELECT * FROM t1RIGHT JOIN t2 ON t1.id = t2.idLEFT JOIN t3 ON t2.id = t3.idUNIONSELECT * FROM t1RIGHT JOIN t2 ON t1.id = t2.idRIGHT JOIN t3 ON t2.id = t3.id

    Posted by Tobias Riemenschneider on September 26 2006 12:54pm [Delete][Edit]

    The result of a full outer join betwee tables A and B includes:

    - rows from the result of the inner join- rows from A that don't have corresponding rows in B- rows from B that don't have corresponding rows in A

    Formally, the corresponding SQL statement looks like this:

    SELECT *FROM A JOIN B ON A.id = B.idUNION ALLSELECT *FROM A LEFT JOIN B ON A.id = B.idWHERE B.id IS NULLUNION ALLSELECT *FROM A RIGHT JOIN B ON A.id = B.idWHERE A.id IS NULL

    Due to the fact that the first union represents a left outer join, the statement can be simplified:

    http://dev.mysql.com/doc/mysql/comment.php?id=8023&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8023&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8023&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8023http://dev.mysql.com/doc/mysql/comment.php?id=8023http://dev.mysql.com/doc/mysql/comment.php?id=8023http://dev.mysql.com/doc/mysql/comment.php?id=8023http://dev.mysql.com/doc/mysql/comment.php?id=8023&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    13/15

    SELECT *FROM A LEFT JOIN B ON A.id = B.idUNION ALLSELECT *FROM A RIGHT JOIN B ON A.id = B.id

    WHERE A.id IS NULL

    Posted by [name withheld] on March 16 2007 3:51pm [Delete][Edit]

    The example posted on September 12 2006 about how to emulate FULL OUTER JOIN usingUNION has a subtle problem. Assume you have 3 tables, each with one single colum "id" and 4rows.t0 contains 1,3,5,7,t1 contains 2,3,6,7,t2 contains 4,5,6,7(ti contains j iff 2^i xor j = 1).

    The suggested solution:

    SELECT * FROM t0 LEFT JOIN t1 ON t0.id = t1.id LEFT JOIN t2 ON t1.id = t2.id UNIONSELECT * FROM t0 RIGHT JOIN t1 ON t0.id = t1.id LEFT JOIN t2 ON t1.id = t2.id UNIONSELECT * FROM t0 RIGHT JOIN t1 ON t0.id = t1.id RIGHT JOIN t2 ON t1.id = t2.id

    produces

    id id id1 NULL NULL

    3 3 NULL5 NULL NULL7 7 7NULL 2 NULLNULL 6 6NULL NULL 4NULL NULL 5

    where "5" appears 2 times. To get the correct result, use only LEFT JOIN, start once with eachtable, and name the columns:

    SELECT t0.id as id0, t1.id as id1, t2.id as id2 FROM t0 LEFT JOIN t1 USING(id) LEFT JOINt2 USING(id) UNIONSELECT t0.id as id0, t1.id as id1, t2.id as id2 FROM t1 LEFT JOIN t0 USING(id) LEFT JOINt2 USING(id) UNIONSELECT t0.id as id0, t1.id as id1, t2.id as id2 FROM t2 LEFT JOIN t1 USING(id) LEFT JOINt0 USING(id)ORDER BY COALESCE(id0,id1,id2)

    http://dev.mysql.com/doc/mysql/comment.php?id=8471&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8471&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8471&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8471http://dev.mysql.com/doc/mysql/comment.php?id=8471http://dev.mysql.com/doc/mysql/comment.php?id=8471http://dev.mysql.com/doc/mysql/comment.php?id=8471http://dev.mysql.com/doc/mysql/comment.php?id=8471&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    14/15

    The ORDER BY is optional. The length of the query grows as the square of the number oftables, which is quite bad. FULL OUTER JOIN would be really welcome.

    Posted by Balaji Devarajan on March 18 2007 7:50pm [Delete][Edit]

    I found this union LEFT JOIN AND RIGHT JOIN, display all the columns from the two tablesvery usefull for me...

    mysql> select * from NAME;

    +------+------+

    | ID | NAME |+------+------+

    | 1 | bala || 2 | renu |+------+------+

    mysql> select * from DESCR;+------+-------+| ID | DESCR |

    +------+-------+| 2 | BBB || 3 | CCC |

    +------+-------+

    mysql> SELECT t1.ID,t1.NAME,t2.DESCR FROM NAME t1 LEFT JOIN DESCR t2 ON(t1.ID = t2.ID) UNION SELECT t2.ID,t1.NAME,t2.DESCR FROM NAME t1 RIGHT JOINDESCR t2 ON (t1.ID = t2.ID);+------+------+-------+

    | ID | NAME | DESCR |+------+------+-------+

    | 1 | bala | NULL || 2 | renu | BBB || 3 | NULL | CCC |

    +------+------+-------+

    Posted by Ted Conn on December 21 2007 9:38am [Delete][Edit]

    Use group_concat to coalesce fields that are otherwise impossible when using an inner join.

    For example:

    SELECT T1.a,T1.b,T2.a,GROUP_CONCAT(T2.b ORDER BY T2.b DESC SEPARATOR '|') as

    d FROM T1 INNER JOIN T2 ON T1.a = T2.b GROUP BY T1.a

    When this query might otherwise duplicate rows, adding the group_concat coalesces them as ablob which when printed returns all the values concatenated by the defined separator string!

    Posted by Wiebe Cazemier on March 25 2008 7:18pm [Delete][Edit]

    http://dev.mysql.com/doc/mysql/comment.php?id=8475&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8475&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8475&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8475http://dev.mysql.com/doc/mysql/comment.php?id=8475http://dev.mysql.com/doc/mysql/comment.php?id=8475http://dev.mysql.com/doc/mysql/comment.php?id=9163&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9163&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9163&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9163http://dev.mysql.com/doc/mysql/comment.php?id=9163http://dev.mysql.com/doc/mysql/comment.php?id=9163http://dev.mysql.com/doc/mysql/comment.php?id=9365&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9365&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9365&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9365http://dev.mysql.com/doc/mysql/comment.php?id=9365http://dev.mysql.com/doc/mysql/comment.php?id=9365http://dev.mysql.com/doc/mysql/comment.php?id=9365http://dev.mysql.com/doc/mysql/comment.php?id=9365&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9163http://dev.mysql.com/doc/mysql/comment.php?id=9163&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=8475http://dev.mysql.com/doc/mysql/comment.php?id=8475&action=delete
  • 8/14/2019 12.2.7.1. JOIN Syntax

    15/15

    For those who don't fully understand the concept of joins, I wrote an article which might help.

    http://www.halfgaar.net/sql-joins-are-easy

    Posted by Geoffrey De Smet on July 29 2008 8:03am [Delete][Edit]

    Faking a full outer join through unions doesn't work when you need to do grouping to calculatetotals.

    For example:

    select a.x, a.y, sum(a.price), sum(b.price)from A a full join B b on a.x = b.x and a.y = b.ywhere ...group by a.x, a.yorder by a.x, a.y

    A full join is needed because there are (x,y) combinations that exist only in A or only in B.A group by is needed because in B the (x,y) combination isn't unique.

    http://www.halfgaar.net/sql-joins-are-easyhttp://www.halfgaar.net/sql-joins-are-easyhttp://dev.mysql.com/doc/mysql/comment.php?id=9629&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9629&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9629&action=deletehttp://dev.mysql.com/doc/mysql/comment.php?id=9629http://dev.mysql.com/doc/mysql/comment.php?id=9629http://dev.mysql.com/doc/mysql/comment.php?id=9629http://dev.mysql.com/doc/mysql/comment.php?id=9629http://dev.mysql.com/doc/mysql/comment.php?id=9629&action=deletehttp://www.halfgaar.net/sql-joins-are-easy