I'm more mysql than php but are you binding the $guestid php variable twice? You need to supply a variable for each ?
placeholder in prepared statements and presumably so in mysqli. In a native prepared statement on the server, the ? is legal within an IF() but then again so is ? = ?, which apparently mysqli doesn't allow.
But also, you could rewrite the query:
IF(r.eventId = e._id AND r.guestId = i.guestId, 1, 0) AS 'RSVP-ed'
We know that i.guestId has to contain the guestId you're interested in, because you've specified it in the where clause so we should be able to compare it this way.
However, there seem to be other issues with your query.
LEFT JOIN rsvpList AS r ON r.eventId = e._id
It seems like this should actually be:
LEFT JOIN rsvpList AS r ON r.eventId = e._id AND r.guestId = i.guestId
...because otherwise you're joining all of the rsvpList entries for that event, not just those for the guest in question. You may have tried to filter for this in the WHERE
clause at some point, which doesn't work if they haven't rsvp'ed.
This change also illustrates that the first comparison in your IF() is actually unnecessary.
IF(r.eventId = e._id AND r.guestId = i.guestId, 1, 0) AS 'RSVP-ed'
We know that r.eventId will match e._id OR will be null if no RSVP, so we don't need to test it, because r.guestId will be what we want or null if no rsvp, so this becomes simply:
r.guestId IS NOT NULL as `RSVP-ed`
the truthiness of the assertion that r.guestId is not null in the joined-up result set is returned as a 1 or 0, and r.guestId will be null with no rsvp because there's no matching row in rsvpList for that guestId.
An equivalent and slightly more intuitive (but redundant) expression of that would be
IF(r.guestId IS NOT NULL,1,0) as `RSVP-ed`
Best Answer
This is for all intents and purposes, a Cartesian Join.
It is definitely out of the question to join every row and pass through the data a single time since you do not know the running time or the amount of temp table space needed.
Perhaps you could do the following:
table1
is small andtable2
is smallSELECT * FROM table1;
and load it into an array in memorySELECT * FROM table2;
and load it into an array in memorytable1
is large andtable2
is smallSELECT * FROM table2;
and load it into an array in memorytable1
but the inner loop reads the data fromtable2
from the array.table1
is large andtable2
is largeSELECT * FROM table1;
and load it into a local text fileSELECT * FROM table2;
and load it into a local text fileSELECT A.*,B.* FROM table1 A,table2 B;
I also suggest not using
SELECT *
but usingSELECT col1,col2,...
reading only needed columns. This would significant reduce round trip times for queries.The point behind these suggestions is to avoid a process of opening and close threads of data that is fetch repeatedly.
UPDATE 2013-06-04 18:47 EDT
Perhaps you could write a stored procedure, run the SP to collect all the data on the server side, then simply read the data in one pass. Again, this will reduce rounds trips of calls, opening and closing DB Connections. All the PHP logic would thus be done is the SP.