MySQL outer join substitute -


i working on game inventory management system , display owner's restock wish list , count of customer buy reservations each game in single table. wrote query thought working, noticed omits games there reservations aren't in restock wish list. query below:

select rwl.*, g.gamename, coalesce(payyes, 0) payyes, coalesce(payno, 0) payno restockwishlist rwl, games g         left join         (select gameid, count(if(prepaid='yes', 1, null)) payyes, count(if(prepaid='no', 1, null)) payno reservationsbuy group gameid) res         on res.gameid = g.gameid         rwl.gameid = g.gameid; 

query results: gameid, quantity, gamename, payyes, payno

1, 4, castle seasons, 0, 0

2, 2, few acres of snow, 0, 0

18, 4, alhambra, 0, 0

54, 2, big boggle, 2, 0

apparently solution problem use full outer join instead of left join, mysql doesn't support function. have spent hours trying translate union structure, can't quite work correctly. close i've got:

select rwl.*, res.gameid, res.payyes, res.payno restockwishlist rwl left join (select gameid, count(if(prepaid='yes', 1, null)) payyes, count(if(prepaid='no', 1, null)) payno reservationsbuy group gameid) res         on res.gameid = rwl.gameid union select rwl.*, res.gameid, count(if(prepaid='yes', 1, null)) payyes, count(if(prepaid='no', 1, null)) payno reservationsbuy res left join restockwishlist rwl on rwl.gameid = res.gameid; 

query results: gameid, quantity, gameid, payyes, payno

1, 4, null, null, null

2, 2, null, null, null

18, 4, null, null, null

54, 2, 54, 2, 0

null, null, 30, 3, 1

(sorry, don't know how nicely format query table results in stackoverflow.)

i want query display wrote it, missing values reservationsbuy. specific please?

tables:

create table if not exists restockwishlist ( gameid int(6), quantity int(3) not null, primary key (gameid), foreign key (gameid) references games(gameid) on update cascade on delete cascade);  create table if not exists reservationsbuy ( gameid int(6), customeremail varchar(25) not null, customername varchar(25) not null, datereserved datetime not null,     #date customer files game reservation datepurchased datetime,             #date board , brew restocks game dateclaimed datetime,               #date customer physically claims game prepaid enum('yes', 'no') not null, primary key (gameid, customeremail), foreign key (gameid) references games (gameid) on update cascade on delete cascade); 

sample data: restockwishlist:

gameid, quantity

1, 4

2, 2

18, 4

54, 2

reservationsbuy:

gameid, customeremail, customername, datereserved, datepurchased, dateclaimed, prepaid

30, wonder@woman.com, diana, 2015-04-24 14:46:05, null, null, yes

54, boggie@marsh.com, boggie, 2015-04-24 14:43:32, null, null, yes

54, manny@second.com, manny, 2015-04-27 19:48:22, null, null, yes

43, old@mom.com, grandma, 2015-04-23 22:32:03, null, null, no

expected output: gameid, quantity, gamename, payyes, payno

1, 4, castle seasons, 0, 0

2, 2, few acres of snow, 0, 0

18, 4, alhambra, 0, 0

30, 0, arkham horror, 1, 0

43, 0, bananagrams, 0, 1

54, 2, big boggle, 2, 0

(games table not particularly important query. relevance both reservationsbuy , restockwishlist connected games gameid)

you're on right track using full outer join, have implementation incorrect.

a full outer join in mysql can thought of union of left join , right join. in query, you're trying approximate treating right join part of logic inverse left join of 2 tables, first part doesn't work because it's not subselect same group by sequence first left join.

simplest thing take first left join query stanza, copy second stanza, , replace left join right join, link results games table, so:

select g.gameid, ifnull(q.quantity, 0) quantity, g.gamename,        ifnull(q.payyes, 0) payyes, ifnull(q.payno, 0) payno   games g        inner join (          select ifnull(rwl.gameid, res.gameid) gameid, rwl.quantity,                 res.payyes, res.payno            restockwishlist rwl                 left join (                    select gameid, count(if(prepaid='yes', 1, null)) payyes,                           count(if(prepaid='no', 1, null)) payno                      reservationsbuy                  group gameid                 ) res on res.gameid = rwl.gameid           union          select ifnull(rwl.gameid, res.gameid) gameid, rwl.quantity,                 res.payyes, res.payno            restockwishlist rwl                 right join (                     select gameid, count(if(prepaid='yes', 1, null)) payyes,                            count(if(prepaid='no', 1, null)) payno                       reservationsbuy                   group gameid                 ) res on res.gameid = rwl.gameid        ) q on g.gameid = q.gameid 

sql fiddle results