Как выбрать элемент, ниже и выше в MYSQL - PullRequest
1 голос
/ 13 июня 2009

У меня есть база данных с идентификаторами, которые не являются целыми числами, как это:

b01
b02
b03
d01
d02
d03
d04
s01
s02
s03
s04
s05

и т.д.. Буквы обозначают тип продукта, номера следующих в этой группе.

Я бы хотел иметь возможность выбрать идентификатор, скажем, d01, и вернуть b03, d01, d02. Как мне это сделать в MYSQL?

Ответы [ 6 ]

2 голосов
/ 13 июня 2009

Вот еще один способ сделать это, используя UNION s. Я думаю, что это немного легче понять и более гибко, чем принятый ответ. Обратите внимание, что в примере предполагается, что поле id уникально, что, как представляется, основано на вашем вопросе.

В приведенном ниже SQL-запросе предполагается, что ваша таблица называется demo и имеет единственное уникальное поле id, а таблица заполнена значениями, перечисленными в вашем вопросе.

( SELECT id FROM demo WHERE STRCMP ( 'd01', id ) > 0 ORDER BY id DESC LIMIT 1 )
UNION ( SELECT id FROM demo WHERE id = 'd01' ORDER BY id ) UNION 
( SELECT id FROM demo WHERE STRCMP ( 'd01', id ) < 0 ORDER BY id ASC LIMIT 1 ) 
ORDER BY id

Это дает следующий результат: b03, d01, d02.

Это гибкое решение, поскольку вы можете изменить каждый из операторов LIMIT 1 на LIMIT N, где N - любое число. Таким образом, вы можете получить предыдущие 3 строки и следующие 6 строк, например.

1 голос
/ 16 декабря 2010

Примечание: это из M $ SQL Server, но единственное, что нужно настроить - это функция isnull.

select *
from test m
where id between isnull((select max(id) from #test where col < 'd01'),'d01')
             and isnull((select min(id) from #test where col > 'd01'),'d01')
0 голосов
/ 13 июня 2009

Как насчет использования курсора? Это позволит вам пройти по возвращенному набору по одной строке за раз. используя его с двумя переменными (такими как «current» и «last»), вы можете перемещаться по результату, пока не достигнете своей цели. Затем верните значение «last» (для n-1), введенную вами цель (n), а затем пройдитесь / повторите и еще раз и верните «current» (n + 1).

0 голосов
/ 13 июня 2009
mysql> describe test;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | varchar(50) | YES  |     | NULL    |       | 
+-------+-------------+------+-----+---------+-------+

mysql> select * from test;
+------+
| id   |
+------+
| b01  | 
| b02  | 
| b03  | 
| b04  | 
+------+

mysql>  select * from test where id >= 'b02' LIMIT 3;
+------+
| id   |
+------+
| b02  | 
| b03  | 
| b04  | 
+------+
0 голосов
/ 13 июня 2009

Хотя это и не прямой ответ на ваш вопрос, я лично не стал бы полагаться на естественный порядок, поскольку он может изменить дуэт на импорт / экспорт и вызвать побочные эффекты, которые непросто понять другим программистам. Как насчет создания альтернативного индекса INTEGER и запуска другого запроса? "ГДЕ id> ... yourdesiredid ... LIMIT 1"?

0 голосов
/ 13 июня 2009

Найдите целевую строку,

SELECT p.id FROM product WHERE id = 'd01'

и строка над ней без других строк между ними.

LEFT JOIN product AS p1 ON p1.id > p.id    -- gets the rows above it

LEFT JOIN       -- gets the rows between the two which needs to not exist
        product AS p1a ON p1a.id > p.id AND p1a.id < p1.id

и аналогично для строки под ней. (Оставлено как упражнение для читателя.)

По моему опыту, это также весьма эффективно.

    SELECT
        p.id, p1.id, p2.id
    FROM
        product AS p
    LEFT JOIN
        product AS p1 ON p1.id > p.id
    LEFT JOIN 
        product AS p1a ON p1a.id > p.id AND p1a.id < p1.id
    LEFT JOIN
        product AS p2 ON p2.id < p.id
    LEFT JOIN 
        product AS p2a ON p2a.id < p.id AND p2a.id > p2.id
    WHERE
        p.id = 'd01'
        AND p1a.id IS NULL
        AND p2a.ID IS NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...