You need an outer join.
If you don't care about the order in which the "won" trophies appear, you could very simply do the following (because winner_id
will be NULL
for those trophies that have not been won and NULL
is ordered "after" all other results in a descending order):
SELECT * FROM
trophies_list
NATURAL LEFT JOIN trophies_won
ORDER BY winner_id DESC, RAND();
Of course, if when you said that "all trophies that have not been won should be in a random order" you meant you merely didn't care about the order, you can omit the trailing ", RAND()
".
UPDATE
In response to your comments, I think you're actually looking for something more like:
SELECT trophies_list.*, NOT ISNULL(trophies_won.winner_id) AS won FROM
trophies_list
LEFT JOIN trophies_won ON (
trophies_won.trophy_id = trophies_list.trophy_id
AND trophies_won.winner_id = 43
)
ORDER BY won DESC, RAND();
By performing an outer join ON
the criteria you're after, you can identify amongst the list of all trophies which match that criteria and which don't. In this case, which trophies have been won by the specified winner and which haven't.
The ORDER BY
clause then ensures that the results are ordered with those trophies that have been won appearing first, followed by those that have not; within those tiers, the order is randomised (again, if you simply don't care about the order you can remove the , RAND()
part which is adding unnecessary overhead).