MySQL: интервал вокруг столбца id и возвращает другой из подзапроса с несколькими столбцами

#mysql #in-subquery

#mysql #в подзапросе

Вопрос:

Я хотел бы выполнить запрос из таблицы, в которой содержимое выглядит так :

 id | col1 | col2 | col3
-----------------------
1  | i_11 | i_12 | i_13
2  | i_21 | i_22 | i_23
3  | i_31 | i_32 | i_33
.. | ...  | ...  | ...

SELECT col1 FROM table WHERE id IN
(SELECT id-1, id 1 FROM table WHERE col1='xxx' AND col2='yyy' AND col3='zzz')
 

Цель состоит в том, чтобы получить интервал [id-1, id 1] на основе id столбца, который возвращает содержимое, хранящееся в col1 for id-1 и id 1 . Подзапрос работает, но я предполагаю, что у меня проблема с самим запросом, поскольку у меня ошибка «Операнд должен содержать только один столбец». Я понимаю это, но я не вижу другого способа сделать это в одном запросе?

Я совершенно уверен, что есть довольно простое решение, но на данный момент я не могу его понять, даже после того, как внимательно прочитал другие сообщения о подзапросах с несколькими столбцами…

Спасибо за любую помощь 🙂

Ответ №1:

Единственный способ, которым я могу думать, чтобы сделать это прямо сейчас, это так:

 SELECT col1 
FROM table T
WHERE id BETWEEN (SELECT id FROM table WHERE col1='xxx' AND col2='yyy' AND col3='zzz') -1 
    and (SELECT id FROM table WHERE col1='xxx' AND col2='yyy' AND col3='zzz')  1
 

Ответ №2:

Ваша проблема в том, что вы извлекаете два значения — но в виде списка, а не набора. Оптимизатор SQL не может видеть 1,3 как набор из двух элементов, когда они представлены в одной строке. Также может потребоваться приведение.

Это должно сработать.

 SELECT col1 FROM table WHERE id in 
(
    select cast(id as int) -1 from table where col1='i_21'
    union
    select cast(id as int)  1 from table where col1='i_21'
)
 

Комментарии:

1. Спасибо! Это действительно работает, но для выполнения требуется слишком много времени (например, 20 секунд в таблице 4000rows!)