Here's a mini-tutorial on left join that should solve your problem. First, let's make a smaller example. (It would have been helpful if you had done that and formatted your select so it could be read when you posted the question ;-) Here are 2 tables:
select * from header; select * from placement; +------+ +------+-----------+ | code | | code | product | +------+ +------+-----------+ | 6 | | 6 | NOSUCH | | 7 | | 7 | OVRLCKBDG | | 8 | | 7 | FUBAR | +------+ +------+-----------+ You want: Info for header 6, and, if any, info for placement (6, '1029106') Info for header 7, and, if any, info for placement (7, 'OVRLCKBDG') Let's look at what a left join is. For a SQL query, select A.*, B.* from A left join B on <condition>; returns two things, (1) Matching rows from A and B, as would be returned by SELECT A.*, B.* from A, B where <condition>; (2) Rows of the form A.*, null, ..., null where those rows in A are included that do NOT participate in the match in (1), followed by nulls representing the columns of B. So, in our example, select header.*, placement.* from header left join placement on header.code = placement.code; gives us all of the header codes and the matching placements: +------+------+-----------+ | code | code | product | +------+------+-----------+ | 6 | 6 | NOSUCH | | 7 | 7 | OVRLCKBDG | | 7 | 7 | FUBAR | | 8 | NULL | NULL | +------+------+-----------+ Well, we don't want all of the matching placements; we just want the specific matches listed above. So, let's add these to the left join condition: select header.*, placement.* from header left join placement on header.code = placement.code and ( header.code = 6 and placement.product = '1029106' or header.code = 7 and placement.product = 'OVRLCKBDG' ); This gives us the placements we want, but there are too many headers: +------+------+-----------+ | code | code | product | +------+------+-----------+ | 6 | NULL | NULL | | 7 | 7 | OVRLCKBDG | | 8 | NULL | NULL | +------+------+-----------+ So. finally, we get rid of the extra headers by adding a where clause: select header.*, placement.* from header left join placement on header.code = placement.code and ( header.code = 6 and placement.product = '1029106' or header.code = 7 and placement.product = 'OVRLCKBDG' ) where header.code in (6, 7); This gives the desired result: +------+------+-----------+ | code | code | product | +------+------+-----------+ | 6 | NULL | NULL | | 7 | 7 | OVRLCKBDG | +------+------+-----------+ ==================== This is a bit ugly, in that the header.code's are listed twice, and there are a lot of literals in the select statement. It might be better to use a temporary table to hold the desired (code, product) pairs. Then, we join the 3 tables with a select that seems less complex: Here's the temporary table: select * from tt; +------+-----------+ | code | product | +------+-----------+ | 6 | 1029106 | | 7 | OVRLCKBDG | +------+-----------+ and here's the 3-table join: select header.*, placement.* from header inner join tt on header.code = tt.code left join placement on tt.code = placement.code and tt.product = placement.product; which also gives the desired result: +------+------+-----------+ | code | code | product | +------+------+-----------+ | 6 | NULL | NULL | | 7 | 7 | OVRLCKBDG | +------+------+-----------+ > From: "Mark Colvin" <[EMAIL PROTECTED]> > To: "MySQL Mailing List \(E-mail\)" <[EMAIL PROTECTED]> > Subject: MySQL Left Join Query > Date: Mon, 18 Nov 2002 08:05:51 -0000 > > I have a two table query where I want to return records from the first table > and if they have corresponding details in my second table I wish to return > those as well. A sample sql statement I am using is as follows: > > select decheader.code, decheader.height, decheader.width, > decplacement.position, decplacement.product from decheader left join > decplacement on decheader.code = decplacement.code where (decheader.code = > '00007' and decplacement.product = 'OVRLCKBDG') or (decheader.code = '00006' > and decplacement.product = '1029106') or (decheader.code = '00005' and > decplacement.product = '1029103') or (decheader.code = '00005' and > decplacement.product = '1029104') or (decheader.code = '00005' and > decplacement.product = '1029105') or (decheader.code = '00005' and > decplacement.product = '1029106') or (decheader.code = '00004' and > decplacement.product = '1029104') or (decheader.code = '00004' and > decplacement.product = '1029105') > > In the above example, all of the codes exist in the decheader table but only > code 00007 has a corresponding product in the decplacement table. I would > wish to return all the decheader details for the above codes and the > decplacement details for code 00007 as well. This statement actually only > gives me the details for code 0007 and nothing else. I should add that for > each record in the decheader table, there may be one, none or many recordsh > in the decplacement table but I will only be interested in a specific one. I > hope this makes some sort of sense!! --------------------------------------------------------------------- Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail <[EMAIL PROTECTED]> To unsubscribe, e-mail <[EMAIL PROTECTED]> Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php