2011-02-04 3 views
0

таблица индексируется по имениэто можно сделать в одном запросе sql?

поля для заданного значения имени «name1» дайте мне эту строку, а также N строк до и N строк после того, как (по алфавиту)

+0

Вы можете объяснить, что хотите? – kacalapy

+0

У меня есть способ сделать это в двух операциях select и переменной, действительно ли это должно быть в 1 select statement? – gh9

+0

Там, мой довольно медленный для больших наборов данных, но он делает все это в 1 запросе. – gh9

ответ

0

Следующая получает вам строку с именем = 'name4', две строки до этого и две строки после этого.

drop table t; 

create table t(
    name varchar(20) 
    ,primary key(name) 
); 

insert into t(name) values('name1'); 
insert into t(name) values('name2'); 
insert into t(name) values('name3'); 
insert into t(name) values('name4'); 
insert into t(name) values('name5'); 
insert into t(name) values('name6'); 
insert into t(name) values('name7'); 

commit; 

(select name from t where name = 'name4') 
    union all 
(select name from t where name > 'name4' order by name asc limit 2) 
    union all 
(select name from t where name < 'name4' order by name desc limit 2); 


+-------+ 
| name | 
+-------+ 
| name1 | 
| name2 | 
| name4 | 
| name5 | 
| name6 | 
+-------+ 

Edit: Добавлено нисходящем порядке, как было отмечено cyberkiwi (в противном случае я бы получил «первый» 2 пунктов на неправильном конце).

+0

Возможно, вы захотите заказать по названию 'DESC' в последней части – RichardTheKiwi

+1

Результат не так: Нет' name3' и дополнительного 'name1'. Гарантирует ли MySQL ограничение в подзапросе? Кроме того, должен ли быть «порядок» во всех профсоюзах? (У разных RDMB есть странные представления о том, когда операции «просмотра» вступают в силу.) –

1

Выполнено ли это в двух операциях выбора, заменяя номер 5 тем, что вы хотите, чтобы вы были N, и измените имя таблицы, и это сделает это. Также замените звездочку на правильные имена столбцов. Дайте мне знать, если у вас возникнут проблемы с этим.

select * from 
    (
     Select * 
     ,row_number() over (order by firstname desc) as 'rowNumber' 
     from attendees 
    ) as temp 
where rowNumber between 
(
    select rownumber-1 
    from 
     (
      Select *, row_number() over (order by firstname desc) as 'rowNumber' 
      from attendees 
     ) as temp 
    where firstname = 'name1') AND (
    select rownumber+1 
    from 
     (
      Select *, row_number() over (order by firstname desc) as 'rowNumber' 
      from attendees 
     ) as temp 
    where firstname = 'name1') 
+0

За исключением факта, что MySQL не предоставляет 'row_number()' :-) (Это заставляет меня кричать на некоторые из уродливых хаков, используемых в MySQL, рассмотренных «normal».) Если это SQL Server, он может быть сведен к CTE. Тем не менее, +1 для ответа. –

+0

Это слишком болезненно для чтения, и производительность будет мрачной - просто используйте UNION ALL и TOP N .. как запрос Cybernate – RichardTheKiwi

Смежные вопросы