96 votes

Comment récupérer le premier et le dernier enregistrement d'une requête sql ?

Dans PostgreSQL, j'exécute une requête avec plusieurs conditions qui renvoie plusieurs lignes, ordonnées par l'une des colonnes. Exemple :

SELECT <some columns> 
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC

Comment obtenir la première et la dernière ligne de cette requête ?

144voto

Mitch Wheat Points 169614

[Mise en garde : ce n'est peut-être pas la façon la plus efficace de procéder] :

(SELECT <some columns>
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC
LIMIT 1)

UNION ALL

(SELECT <some columns>
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date ASC    
LIMIT 1)

42voto

a_horse_with_no_name Points 100769

Vous pouvez essayer ceci, cela pourrait être plus rapide que de faire deux requêtes :

select <some columns>
from (
    SELECT <some columns>,
           row_number() over (order by date desc) as rn,
           count(*) over () as total_count
    FROM mytable
    <maybe some joins here>
    WHERE <various conditions>
) t
where rn = 1
   or rn = total_count
ORDER BY date DESC

25voto

Robo Points 1276

Premier enregistrement :

SELECT <some columns> FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date ASC
LIMIT 1

Dernier record :

SELECT <some columns> FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC
LIMIT 1

19voto

neha Points 61

Dernier record :

SELECT * FROM `aboutus` order by id desc limit 1

premier enregistrement :

SELECT * FROM `aboutus` order by id asc limit 1

13voto

Natan Points 3

Dans toutes les manières exposées de faire jusqu'à présent, il faut passer par le scan deux fois, une pour la première rangée et une pour la dernière rangée.

En utilisant la fonction de fenêtre "ROW_NUMBER() OVER (...)" et "WITH Queries", vous pouvez effectuer un seul balayage et obtenir les deux éléments.

Fonction de la fenêtre : https://www.postgresql.org/docs/9.6/static/functions-window.html

WITH Queries : https://www.postgresql.org/docs/9.6/static/queries-with.html

Exemple :

WITH scan_plan AS (
SELECT
    <some columns>,
    ROW_NUMBER() OVER (ORDER BY date DESC) AS first_row, /*It's logical required to be the same as major query*/
    ROW_NUMBER() OVER (ORDER BY date ASC) AS last_row /*It's rigth, needs to be the inverse*/
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC)

SELECT
    <some columns>
FROM scan_plan
WHERE scan_plan.first_row = 1 OR scan_plan.last_row = 1;

De cette manière, vous n'effectuerez les relations, les filtrages et les manipulations de données qu'une seule fois.

Essayez d'EXPLAIN ANALYZE dans les deux sens.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X