select a.name, b.marks from a join b on a.num = b.num
union all
select a.name, b.marks from a, b where a.num = 0
Вы можете найти, что это работает лучше, чем предложение where с "ИЛИ". Хотя, честно говоря, вы не можете, нет никакого реального способа обойти необходимость сканирования всего A и B так или иначе. Но часто бывает полезно попросить планировщиков разделить условия «ИЛИ» на объединения.
EDIT:
Просто хотел немного рассказать об этом. Причина, по которой это может быть выгодно, состоит в том, что две части профсоюзов получают выгоду от того, что они делаются совершенно по-разному. Например, вторая часть может начинаться с поиска всех строк в a с (num = 0), тогда как первая часть может быть более подходящей для выполнения полного сканирования поисков a и index / поиска хешей в b или объединения индексов на a (число) и b (число).
Я также скажу, что этот запрос возникает из-за сомнительного замысла. Вы не можете иметь ограничение внешнего ключа от a (num) на b (num), даже если это имеет смысл, потому что (a.num = 0) не будет соответствовать ни одной строке в b. Если вы добавили строки в b с (num = 0, marks = 90) и (num = 0, marks = 40), тогда ваш запрос можно было бы легко написать с помощью простого внутреннего соединения. Хотя это верно, это означает, что для каждой возможной отметки нужно поддерживать две строки, но это можно сделать с помощью триггера, который обнаруживает вставки с ненулевым значением для num и выполняет дополнительную вставку с num = 0. Я полагаю, у каждого подхода есть свои плюсы и минусы. Но мне действительно очень нравится помещать ограничения fkey в базы данных, и отсутствие их в таком случае заставило бы меня нервничать - что произойдет, если запись в a получит число, которого нет в b? что произойдет, если строка в b будет удалена?