web-dev-qa-db-fra.com

Comment obtenir le premier et le dernier enregistrement à partir d'une requête SQL?

J'ai une table dans PostgreSQL , j'exécute une requête avec plusieurs conditions qui renvoie plusieurs lignes, ordonnées par l'une des colonnes. En général c'est:

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

Maintenant, je suis seulement intéressé à obtenir la première et la dernière ligne de cette requête. Je pouvais les obtenir en dehors de la base de données, dans mon application (et c’est ce que je fais en réalité), mais je me demandais si, pour de meilleures performances, je ne devrais pas obtenir de la base de données uniquement ces 2 enregistrements qui m’intéressaient réellement. 

Et si oui, comment modifier ma requête?

53
kender

[Avertissement: cela ne pourrait pas être le moyen le plus efficace de le faire]:

(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)
74
Mitch Wheat

Vous voudrez peut-être 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
25

Premier enregistrement:

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

Dernier enregistrement:

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

dernier enregistrement:

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

premier enregistrement:

SELECT * FROM `aboutus` order by id asc limit 1
11
neha
SELECT * FROM TABLE_NAME WHERE ROWID=(SELECT MIN(ROWID) FROM TABLE_NAME) 
UNION
SELECT * FROM TABLE_NAME WHERE ROWID=(SELECT MAX(ROWID) FROM TABLE_NAME)

ou

SELECT * FROM TABLE_NAME WHERE ROWID=(SELECT MIN(ROWID) FROM TABLE_NAME) 
                            OR ROWID=(SELECT MAX(ROWID) FROM TABLE_NAME)
5
sundeepkumar dv

Dans toutes les façons de faire exposées jusqu'à présent, il faut parcourir deux fois, une pour la première ligne et une pour la dernière.

En utilisant la fonction de fenêtre "ROW_NUMBER () OVER (...)" plus "WITH Queries", vous ne pouvez numériser qu'une fois 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 façon, vous ne ferez qu’une fois les relations, filtrations et manipulations de données.

Essayez quelques explications ANALYSE des deux manières.

4
Natan Medeiros
select *
from {Table_Name}
where {x_column_name}=(
    select d.{x_column_name} 
    from (
        select rownum as rno,{x_column_name}
        from {Table_Name})d
        where d.rno=(
            select count(*)
            from {Table_Name}));
1
Ampolu Balaji
-- Create a function that always returns the first non-NULL item
CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement )
RETURNS anyelement LANGUAGE SQL IMMUTABLE STRICT AS $$
        SELECT $1;
$$;


-- And then wrap an aggregate around it
CREATE AGGREGATE public.FIRST (
        sfunc    = public.first_agg,
        basetype = anyelement,
        stype    = anyelement
);

-- Create a function that always returns the last non-NULL item
CREATE OR REPLACE FUNCTION public.last_agg ( anyelement, anyelement )
RETURNS anyelement LANGUAGE SQL IMMUTABLE STRICT AS $$
        SELECT $2;
$$;

-- And then wrap an aggregate around it
CREATE AGGREGATE public.LAST (
        sfunc    = public.last_agg,
        basetype = anyelement,
        stype    = anyelement
);

Je l'ai eu ici: https://wiki.postgresql.org/wiki/First/last_(aggregate)

0
SELECT 
    MIN(Column), MAX(Column), UserId 
FROM 
    Table_Name
WHERE 
    (Conditions)
GROUP BY 
    UserId DESC

ou

SELECT        
    MAX(Column) 
FROM            
    TableName
WHERE        
    (Filter)

UNION ALL

SELECT        
    MIN(Column)
FROM            
    TableName AS Tablename1
WHERE        
    (Filter)
ORDER BY 
    Column
0
ashish bhatt