Выберите столбцы только для ORDER BY, не возвращая их в результатах

#mysql

#mysql

Вопрос:

Итак, у меня есть сложный INSERT запрос, который помещает информацию в реляционную таблицу на основе информации, полученной из другой таблицы, и с заданными переменными.

Вот запрос:

 INSERT INTO relational (class_id, teacher_id, student_id)
VALUES (
    (SELECT `id`,
        (`name` = "John Smith") as exact_score,
        (`name` RLIKE "[[:<:]]John Smith[[:>:]]") as reg_score,
        (MATCH (`name`) AGAINST ("John Smith")) as match_score
    FROM `teachers`
    WHERE (`title` RLIKE "[[:<:]]John Smith[[:>:]]" || MATCH (`title`) AGAINST ("John Smith"))
    ORDER BY
        CASE WHEN exact_score = 1 THEN exact_score END DESC,
        CASE WHEN reg_score > 1 THEN reg_score END DESC,
        CASE WHEN reg_score = 0 AND exact_score = 0 THEN match_score END DESC),
1, 1);
  

Регулярное выражение требуется, потому что имя может быть Mr. John Smith или John Smith PH.d , и соответствие требуется, потому что имя может быть jon smith , когда сохраненное имя на самом деле просто John Smith .

Запрос select выдает результаты, которые я ищу в 90% случаев, но единственный реальный столбец, который мне нужен, это id . Проблема, с которой я сталкиваюсь, связана с ожидаемым количеством столбцов вставки против количество столбцов, возвращаемое запросом.

Прямо сейчас ВСТАВКА в основном выглядит так:

 INSERT INTO relational (class_id, teacher_id, student_id) VALUES ({{returned id (desired)}}, {{exact score (undesired)}}, {{reg score (undesired)}}, {{match score (undesired)}}, 1, 1);
  

Последнее 1, 1 обеспечивается переменными.

Мой вопрос в том, есть ли способ выбрать столбцы для ORDER BY, но затем исключить их из результатов?

Ответ №1:

Если столбец определен в таблице / представлении, вы можете использовать его в ORDER BY и исключить из результатов. Но в вашем случае вы используете вычисляемые столбцы в ORDER BY , поэтому, если вы хотите опустить эти столбцы, вы должны заменить их ORDER BY соответствующей формулой, например

 ORDER BY
    CASE WHEN (`name` = "John Smith") = 1 THEN (`name` = "John Smith") END DESC
    -- etc...
  

Я думаю, что это не очень хорошее решение. Вместо этого лучше использовать подзапрос:

 INSERT INTO relational (class_id, teacher_id, student_id)
SELECT id,1,1 FROM
    (SELECT `id`,
        (`name` = "John Smith") as exact_score,
        (`name` RLIKE "[[:<:]]John Smith[[:>:]]") as reg_score,
        (MATCH (`name`) AGAINST ("John Smith")) as match_score
    FROM `teachers`
    WHERE (`title` RLIKE "[[:<:]]John Smith[[:>:]]" || MATCH (`title`) AGAINST ("John Smith"))
    ORDER BY
        CASE WHEN exact_score = 1 THEN exact_score END DESC,
        CASE WHEN reg_score > 1 THEN reg_score END DESC,
        CASE WHEN reg_score = 0 AND exact_score = 0 THEN match_score END DESC)
    AS t1;