J'ai le tableau suivant, nommé Example
:
id(int 11) //not autoincriment
value (varchar 100)
Il contient les lignes de données suivantes:
0 100
2 150
3 200
6 250
7 300
Notez que les valeurs id ne sont pas contiguës.
J'ai écrit ce SQL jusqu'à présent:
SELECT * FROM Example WHERE id = 3
Cependant, je ne sais pas comment obtenir la valeur de id
précédente et celle de la suivante id
...
S'il vous plaît aidez-moi à obtenir la valeur précédente et la valeur suivante si id
= 3?
P.S .: dans mon exemple, ce sera: précédent - 150
, suivant - 250
.
Sélectionnez la ligne suivante ci-dessous:
SELECT * FROM Example WHERE id < 3 ORDER BY id DESC LIMIT 1
Sélectionnez la ligne suivante ci-dessus:
SELECT * FROM Example WHERE id > 3 ORDER BY id LIMIT 1
Sélectionnez les deux dans une requête, par exemple. utilisez UNION :
(SELECT * FROM Example WHERE id < 3 ORDER BY id DESC LIMIT 1)
UNION
(SELECT * FROM Example WHERE id > 3 ORDER BY id LIMIT 1)
C'est ce que tu veux dire?
Une solution serait d'utiliser des variables temporaires:
select
@prev as previous,
e.id,
@prev := e.value as current
from
(
select
@prev := null
) as i,
example as e
order by
e.id
Pour obtenir la valeur "next", répétez la procédure. Voici un exemple:
select
id, previous, current, next
from
(
select
@next as next,
@next := current as current,
previous,
id
from
(
select @next := null
) as init,
(
select
@prev as previous,
@prev := e.value as current,
e.id
from
(
select @prev := null
) as init,
example as e
order by e.id
) as a
order by
a.id desc
) as b
order by
id
Vérifiez l'exemple sur SQL Fiddle
Peut-être exagéré, mais cela peut vous aider
s'il vous plaît essayez ceci sqlFiddle
SELECT value,
(SELECT value FROM example e2
WHERE e2.value < e1.value
ORDER BY value DESC LIMIT 1) as previous_value,
(SELECT value FROM example e3
WHERE e3.value > e1.value
ORDER BY value ASC LIMIT 1) as next_value
FROM example e1
WHERE id = 3
Edit: OP mentionné pour récupérer la valeur de id
et la valeur de id
dans un des commentaires afin que le code soit ici SQLFiddle
SELECT value,
(SELECT value FROM example e2
WHERE e2.id < e1.id
ORDER BY id DESC LIMIT 1) as previous_value,
(SELECT value FROM example e3
WHERE e3.id > e1.id
ORDER BY id ASC LIMIT 1) as next_value
FROM example e1
WHERE id = 3
SELECT *,
(SELECT value FROM example e1 WHERE e1.id < e.id ORDER BY id DESC LIMIT 1 OFFSET 0) as prev_value,
(SELECT value FROM example e2 WHERE e2.id > e.id ORDER BY id ASC LIMIT 1 OFFSET 0) as next_value
FROM example e
WHERE id=3;
Et vous pouvez placer votre propre décalage après le mot clé OFFSET
si vous souhaitez sélectionner des enregistrements avec des décalages plus élevés pour les valeurs suivantes et précédentes de l'enregistrement sélectionné.
Cette requête utilise une variable définie par l'utilisateur pour calculer la distance à partir de l'ID cible et une série de requêtes d'encapsulation pour obtenir les résultats souhaités. Un seul passage est fait sur la table, il devrait donc bien fonctionner.
select * from (
select id, value from (
select *, (@x := ifnull(@x, 0) + if(id > 3, -1, 1)) row from (
select * from mytable order by id
) x
) y
order by row desc
limit 3
) z
order by id
Voir un SQLFiddle
Si vous ne vous souciez pas de l'ordre final des lignes, vous pouvez omettre la requête wrapper la plus externe.
Voici ma solution peut vous convenir:
SELECT * FROM Example
WHERE id IN (
(SELECT MIN(id) FROM Example WHERE id > 3),(SELECT MAX(id) FROM Example WHERE id < 3)
)
Si vous n'avez pas d'identifiant, cela a fonctionné pour moi.
Suivant: Sélectionnez * dans le nom de la table où nom de colonne> ordre actuel des données de colonne par nom de colonne Limite ASC 1
Précédent: Sélectionnez * dans le nom de la table où nom de colonne <ordre actuel des données de colonne par nom de colonne DESC limite 1
J'utilise ceci pour une liste de membres où la recherche est sur le nom de famille du membre. Tant que vous avez les données de l'enregistrement actuel, cela fonctionne bien.
Une solution possible si vous avez besoin de tout cela dans une rangée
SELECT t.id, t.value, prev_id, p.value prev_value, next_id, n.value next_value
FROM
(
SELECT t.id, t.value,
(
SELECT id
FROM table1
WHERE id < t.id
ORDER BY id DESC
LIMIT 1
) prev_id,
(
SELECT id
FROM table1
WHERE id > t.id
ORDER BY id
LIMIT 1
) next_id
FROM table1 t
WHERE t.id = 3
) t LEFT JOIN table1 p
ON t.prev_id = p.id LEFT JOIN table1 n
ON t.next_id = n.id
Exemple de sortie:
ID | Valeur | PREV_ID | PREV_VALUE | NEXT_ID | NEXT_VALUE | | ---- | ------- | --------- | ------------ | -------- - | ------------ | | 3 | 200 | 2 | 150 | 4 | 250 |
Voici SQLFiddle démo