Hi,
after reading this interesting discussion, there are some points I disagree, so I've to explain them.

About cross joins, by definition they are joins without conditions, i.e., the cartessian product between any tables. They are called too "comma" joins. Obviously, they are used to populate tables with combinations and other tasks but they haven't too much sense in a relational world (mainly because they doesn't relation anything!).
Once you put any relation condition in the game you will be creating a relation join. Both inner (natural) and outer (left, right and full) joins requires some conditions to join the tables. And, they are practically the same, the only difference is that inner joins only return pairs with records in both tables, where outer joins return those PLUS records without their respective pair.
Talking about how they are retrieved from DB, they are practically equivalent. Each PK in table A in searched in table B and then, records are joined. As, in the relational model, every PK and FK should have an index on it, this search is really quick (unique and index scan, without making full scans to all the table records). And this technique is used by the RDBS both in inner and outer joins. The unique difference is that, in inner joins, if they key isn't found in table B, record is omitted, while in outer joins, the record from A is returned (with all the fields from B set to NULL). But they are completely different from cross joins (no relation at all, remember?).
So outer and inner joins are, speaking of speed, near the same. Other thing is the use of IN clauses. By default, in most DB, such clauses are really a great speed-down problem. Only using some type of specialised indexes (binary and set indexes) can improve queries using this type of sentences. The main reason is that, for each record retrieved, the RDBS has to make n checks to determinate if the value exists in the list. As such list-fileds cannot be indexed properly (individual values) they suppose a full scan of the table. Add spliting the string and converting them to numbers for each check and you will find that IN is really a cpu-eater.
Welll, this was what I want to say. Please, don't take it like a pedantic exposition (it wasn't my intention, sincerely, but sharing my poor skills about RDBS with you). And don't believe all it's true!!

Finally, coming back to Gustav's question, my suggested change to avoid such "Lists" fields is to include the question order in the "quiz_questions_grades" table. As it contains both the quizid and the questionid and its where we really build the quiz, I think it's the correct place to store the order in a normalised way. And about his original question, "get all the quizzes containing a question", what about a simple but effective:
select distinct quiz
from mdl_quiz_question_grades
where question = ?
Ciao 