Когда вы обнаруживаете, что строите «чрезвычайно сложный оператор SQL», обычно лучше сделать шаг назад и переосмыслить.
Помните об этом - подавляющее большинство операций, выполняемых над таблицей базы данных, - это операции выбора, а не вставки или обновления (хотя, конечно, существуют исключения для каждого правила).
Правильное время, чтобы "тратить" циклы ЦП на вычисление таких вещей, как списки авторов, - это когда список меняется, , а не , когда вы просто хотите извлечь информацию.
Добавьте еще один столбец в таблицу книги с именем author_list, а затем создайте триггер вставки / обновления для авторов, чтобы этот столбец перестраивался при каждом изменении автора для определенного номера ISBN.
Это помещает стоимость туда, где она должна быть, и сделает ваш запрос намного проще. Триггер гарантирует, что данные остаются непротиворечивыми, и если вы знаете, что делаете, то можно прервать 3NF.
Что касается подкатегории, оператор case
может быть вашим другом, но функции для отдельных строк при выборе никогда не масштабируются хорошо.
Я бы просто создал набор строк в подкатегориях с идентификатором 0 (по одному для каждой категории) и оставил бы его имя пустым. Тогда это можно сделать простым соединением, не заботясь о производительности. Это также может быть сделано с триггером на категорию, поэтому каждая категория всегда будет иметь подкатегорию 0.
С этими двумя изменениями запрос становится намного менее сложным, что-то вроде:
select b.isbn, b.title, b.author_list, c.name, sc.name, b.price
from Book b, Category c, SubCategory sc
where b.category_id = c.category_id
and b.category_id = sc.category_id
and b.subcategory_id = sc.subcategory_id
order by ...
Этот запрос должен развиваться, так как он использует только базовые уровни реляционной алгебры (то есть, нет функций для каждой строки (включая операторы case), нет подзапросов). И это запрос «старой школы», вы можете получить еще большую производительность, используя явные, а не неявные соединения.
И последнее замечание: в правильной схеме 3NF ISBN не будет указан в таблице авторов. Лучше было бы иметь отдельную таблицу BookAuthor, содержащую ISBN и author_id, для правильного моделирования отношения «многие ко многим». Но вы, возможно, уже изменили это для производительности (я не знаю).