2012-03-23 6 views
9

Voici le tableau d'exemple:MySQL sélectionner avant après la ligne

Column    | 1st record | 2nd record | 3rd record | 4th record | etc<br /> 
id (primary)  | 1   | 5   | 8   | 12   | etc<br /> 
name    | name 1  | name 2  | name 3  | name 4  | etc<br /> 
date    | date 1  | date 2  | date 3  | date 4  | etc<br /> 
callValue (unique) | val1  | val2  | val3  | val4  | etc 

je sélectionne une ligne qui est les données à afficher (par exemple: ramer avec callValue: val3). Mais je ne peux pas trouver une solution pour cela:
Je dois sélectionner la rangée précédente et suivante. Ainsi, dans cet exemple, je dois obtenir des données à partir des lignes vallValue: Val4 et callValue: val2 ou id: 5 et id: 12.

Il ne peut pas être fait avec id = id + -1 parce que id ne fonctionne pas doivent être continues en raison de la suppression des lignes.

Répondre

20

Essayez ceci:

select * from test where callValue = 'val3' 
union all 
(select * from test where callValue < 'val3' order by id desc limit 1) 
union all 
(select * from test where callValue > 'val3' order by id asc limit 1) 

ou

select * from test where id = 8 
union all 
(select * from test where id < 8 order by id desc limit 1) 
union all 
(select * from test where id > 8 order by id asc limit 1) 
+0

homme Merci, vous êtes rapide :) J'ai reçu – bosniamaj

+0

premier message d'erreur, mais mettre() après l'union a résolu :) – bosniamaj

+0

Bienvenue! Je ne suis pas très bon avec la syntaxe mysql-spécifique, désolé :( –

11

Une fois que vous avez l'identifiant 8, vous devriez être en mesure de faire une variation sur:

select * from mytable 
where id < 8 
order by id desc 
limit 1 

et:

select * from mytable 
where id > 8 
order by id asc 
limit 1 

pour l'enregistrement précédent et suivant.

+4

cette solution est plus courte et mieux à comprendre pour tout le monde –

+2

comment savez-vous que c'est mieux pour tout le monde? Vous voulez probablement dire que c'était mieux pour vous-même –

+2

Il est plus court , il utilise une syntaxe plus simple, il est plus lisible, et il a des performances supérieures, je pense qu'il est plus sûr de dire que c'est globalement meilleur – Luciasar

2

Cela fonctionne:

select a.id, a.name, a.date, a.callValue 
FROM 
(
    select @r0 := @r0 + 1 as rownum, id, name, date, callValue from TABLE 
    , (SELECT @r0 := 0) r0 
) a, 
(
    select @r1 := @r1 + 1 rownum, id, name, date, callValue from TABLE 
    , (SELECT @r1 := 0) r1 
) b 
where b.callValue = val3 and b.rownum between (a.rownum-1 and a.rownum+1) 

Il élargit la table en 2 dimensions afin que vous puissiez comparer les lignes de la table de poing à un ensemble de lignes de la seconde.

-1
select * 
from callvalue 
where id < maxd 
(
select max(id) as maxd 
from callvalue 
where id = maxd 
) 
Questions connexes