12
votes

SQL tirant une rangée pour une rangée suivante ou précédente d'une ligne de courant

id    |  photo title     |  created_date

XEi43 |  my family       |  2009 08 04
dDls  |  friends group   |  2009 08 05
32kJ  |  beautiful place |  2009 08 06
EOIk  |  working late    |  2009 08 07 
Say I have the id 32kJ.  How would I get the next row or the previous one?

2 commentaires

Le concept de "suivant" ou "précédent" dépend de la commande. Vous risquez probablement de le faire de manière programmatique, en rétrécissant un jeu de données à l'aide de Ado.net ou d'une autre technologie, puis en boucle dans les enregistrements de cette représentation des données.


Il est facilement faisable si votre champ d'identification était séquentiel et numérique, le fait que vous utilisiez des caractères alphabétiques le rend beaucoup plus délicieux. Scottklarr.com/topic/111/...


6 Réponses :


0
votes

Horrible Hack - Je n'aime pas ça, mais peut marcher ...

with yourresult as
(
select id, photo_title, created_date, ROW_NUMBER() over(order by created_date) as 'RowNum' from your_table
)
-- Previous
select * from yourresult where RowNum = ((select RowNum from yourresult where id = '32kJ') -1)
-- Next
select * from yourresult where RowNum = ((select RowNum from yourresult where id = '32kJ') +1)


2 commentaires

Probablement pas, malheureusement. C'est mysql - j'ai eu un rapide pensez-y hier, mais je n'avais pas beaucoup de temps - j'aurai un autre look ce soir ..


Je reçois cette erreur # 1064 - Vous avez une erreur dans votre syntaxe SQL; Vérifiez le manuel qui correspond à votre version de Server MySQL pour la syntaxe de droite à utiliser à proximité »avec YourResult sous (Sélectionnez Photo_ID, Titre, Ajout_Date, Row_Number () sur (ORD 'à la ligne 1



2
votes

Je me rends compte que vous utilisez mysql, mais simplement pour référence, voici la manière dont vous feriez cela en utilisant les fonctions analytiques d'Oracle, le plomb et le décalage:

select empno, ename, job,
  lag(ename, 1) over (order by ename) as the_guy_above_me,
  lead(ename, 2) over (order by ename) as the_guy_two_rows_below_me
from emp
order by ename


1 commentaires

Vous obtenez ces fonctions analytiques à Postgres 8.4 aussi: P



2
votes

VOULEZ-VOUS LE SUPPORT NEXT / PRÉCÉDRE PAR DATE? Si oui, vous pouvez le faire:

select MyTable.*
from MyTable
join
  (select id
   from MyTable
   where created_date < (select created_date from MyTable where id = '32kJ')
   order by created_date desc, id desc
   limit 1
  ) LimitedTable on LimitedTable.id = MyTable.fund_id;


3 commentaires

Jeremy Stein, pouvez-vous aussi me dire s'il vous plaît, si je peux vérifier la poste de la rangée actuelle à partir de lignes totales (indiquant 6 des 100 rangées), peut-il le faire ou devrais-je étendre la requête, si elle s'étend, alors comment ou quoi Dois-je faire? Je veux juste aussi connaître la position de la rangée actuelle à partir de la totalité des rangées, je peux donc le faire fonctionner avec les prochains et précédents .. Les utilisateurs savent donc où ils sont, comme sur Facebook.


Je veux aussi ajouter du positionnement pour la rangée actuelle, d'autres ensuite et précédentes .. Comment puis-je faire ça? Stackoverflow.com/Questtions/2036425/...


Oui, vous pourriez faire ces choses, mais cela aurait probablement plus de sens de le faire à partir de l'application appelante.



17
votes

C'est ce que j'utilise pour trouver les enregistrements précédents / suivants. Toute colonne de votre table peut être utilisée comme colonne de tri, et aucune jointure ou noisette hacks n'est requise:

Enregistrement suivant (date supérieure à la date actuelle): P>

CREATE TABLE `photo` (
    `id` VARCHAR(5) NOT NULL,
    `title` VARCHAR(255) NOT NULL,
    `created` DATETIME NOT NULL,
    INDEX `created` (`created` ASC),
    PRIMARY KEY (`id`)
)
ENGINE = InnoDB;

INSERT INTO `photo` (`id`, `title`, `created`) VALUES ('XEi43', 'my family',       '2009-08-04');
INSERT INTO `photo` (`id`, `title`, `created`) VALUES ('dDls',  'friends group',   '2009-08-05');
INSERT INTO `photo` (`id`, `title`, `created`) VALUES ('32kJ',  'beautiful place', '2009-08-06');
INSERT INTO `photo` (`id`, `title`, `created`) VALUES ('EOIk',  'working late',    '2009-08-07');

SELECT * FROM photo ORDER BY created;
+-------+-----------------+---------------------+
| id    | title           | created             |
+-------+-----------------+---------------------+
| XEi43 | my family       | 2009-08-04 00:00:00 |
| dDls  | friends group   | 2009-08-05 00:00:00 |
| 32kJ  | beautiful place | 2009-08-06 00:00:00 |
| EOIk  | working late    | 2009-08-07 00:00:00 |
+-------+-----------------+---------------------+


SELECT id, title, MIN(created) AS next_date
FROM photo
WHERE created >
  (SELECT created FROM photo WHERE id = '32kJ')
GROUP BY created
ORDER BY created ASC
LIMIT 1;

+------+--------------+---------------------+
| id   | title        | next_date           |
+------+--------------+---------------------+
| EOIk | working late | 2009-08-07 00:00:00 |
+------+--------------+---------------------+

SELECT id, title, MAX(created) AS prev_date
FROM photo
WHERE created <
  (SELECT created FROM photo WHERE id = '32kJ')
GROUP BY created
ORDER BY created DESC
LIMIT 1;

+------+---------------+---------------------+
| id   | title         | prev_date           |
+------+---------------+---------------------+
| dDls | friends group | 2009-08-05 00:00:00 |
+------+---------------+---------------------+


2 commentaires

Je n'ai pas essayé, mais je suis sûr que cela tirera le résultat, je me demande simplement, lequel si une requête plus rapide.


Pourquoi utilisez-vous des fonctions agrégées si vous avez déjà commandé les résultats et la limiter à 1 rangée?



1
votes

Utiliser Mike's Max / Min Trick Nous pouvons faire les précédents \ Suivant Sauts pour toutes sortes de choses. Cet exemple de MSAccess retournera la fermeture précédente pour chaque enregistrement dans une table de données boursière. Remarque: le '<=' est pour les week-ends et les jours fériés.

 XXX  

... "hier" démontre à l'aide d'une fonction ( date-1 ) saut; nous aurions pu simplement utiliser ... xxx

Le truc est que nous pouvons précédemment \ Next # de quel que soit le (s) avec max \ min et un Fonction de saut ()


0 commentaires

0
votes

J'ai considéré comme identifiant comme clé primaire dans le tableau (et en tant que "numéro de ligne") et l'a utilisé pour comparer chaque enregistrement avec l'enregistrement avant. Le code suivant doit fonctionner. xxx


1 commentaires

Avez-vous besoin de solution pour comparer prev et prochain enregistrement en une seule requête.so essayer ci-dessus ..