web-dev-qa-db-fra.com

Obtenir les lignes précédente et suivante des lignes sélectionnées avec les conditions (WHERE)

Par exemple, j'ai cette déclaration:

my name is Joseph and my father's name is Brian

Cette instruction est divisée par Word, comme dans ce tableau:

------------------------------
|      ID      |   Word      |
------------------------------
|       1      |   my        |
|       2      |   name      |
|       3      |   is        |
|       4      |   Joseph    |
|       5      |   and       |
|       6      |   my        |
|       7      |   father's  |
|       8      |   name      |
|       9      |   is        |
|       10     |   Brian     |
------------------------------

Je veux obtenir le mot précédent et le mot suivant de chaque mot

Par exemple, je veux obtenir le mot précédent et suivant de "nom":

--------------------------
|    my    |  name  |  is |
--------------------------
| father's |  name  |  is |
--------------------------

Comment pourrais-je obtenir ce résultat?

16
mahdi yousefi

vous n'avez pas spécifié votre SGBD. Le code ANSI SQL est la suivante:

select prev_Word, Word, next_Word
from (
    select id, 
           lag(Word) over (order by id) as prev_Word,
           Word,
           lead(Word) over (order by id) as next_Word
    from words
) as t
where Word = 'name';

SQLFiddle: http://sqlfiddle.com/#!12/7639e/1

30

Sans sous-requêtes:

SELECT a.Word 
FROM my_table AS a
JOIN my_table AS b 
ON b.Word = 'name' AND abs(a.id - b.id) <= 1
ORDER BY a.id
6
Will

Pourquoi personne n'a-t-il donné la réponse simple?

SELECT LAG(Word) OVER ( ORDER BY ID ) AS PreviousWord ,
       Word ,
       LEAD(Word) OVER ( ORDER BY ID ) AS NextWord
FROM   words;
6
Nick P

Utilisez Join pour obtenir le résultat attendu pour SQL Server 2005 plus.

    create table words (id integer, Word varchar(20));

    insert into words
    values
    (1 ,'my'),
    (2 ,'name'),
    (3 ,'is'),
    (4 ,'joseph'),
    (5 ,'and'),
    (6 ,'my'),
    (7 ,'father'),
    (8 ,'name'),
    (9 ,'is'),
    (10,'brian');

SELECT A.Id ,  C.Word AS PrevName , 
               A.Word AS CurName , 
               B.Word AS NxtName 
FROM words AS A
LEFT JOIN words AS B ON A.Id = B.Id - 1
LEFT JOIN words AS C ON A.Id = C.Id + 1
WHERE A.Word = 'name'

Résultat:

enter image description here

Démo Fiddler

3
Saravana Kumar

Essaye ça 

SELECT *
FROM   tablename a
WHERE  ID IN(SELECT ID - 1
             FROM   tablename 
             WHERE  Word = 'name') -- will fetch previous rows of Word `name` 
        OR ID IN(SELECT ID + 1
                 FROM   tablename 
                 WHERE  Word = 'name') -- will fetch next rows of Word `name`
        OR Word = 'name' -- to fetch the rows where Word = `name`
1
Pரதீப்

Voici une approche différente si vous voulez que les sélections soient rapides. Cela demande un peu de travail de préparation.

  • Créez une nouvelle colonne (par exemple "phrase") dans la base de données qui contiendra les motsvous voulez. (c'est-à-dire le précédent, l'actuel et le suivant).

  • Ecrivez un déclencheur qui, lors de l'insertion, ajoute le nouveau mot à la phrase de la ligne Précédente et ajoute le mot de la ligne précédente au mot et à la phrase De la nouvelle ligne.

  • Si les mots individuels peuvent changer, vous aurez besoin d'un déclencheur lors de la mise à jour pour que la phrase reste synchronisée.

Ensuite, sélectionnez simplement la phrase. Vous obtenez une vitesse bien supérieure, mais au prix d'un stockage supplémentaire, d'une insertion plus lente et d'une maintenabilité plus difficile. Évidemment, vous devez mettre à jour la colonne phrase pour les enregistrements existants, mais vous avez le code SQL pour le faire dans les autres réponses.

1
mlinth