wake-up-neo.net

Wie erhalte ich den ersten und letzten Datensatz von einer SQL-Abfrage?

Ich habe eine Tabelle in PostgreSQL . Ich führe eine Abfrage mit mehreren Bedingungen aus, die mehrere Zeilen zurückgibt, die nach einer der Spalten sortiert sind. Im Allgemeinen ist es:

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

Jetzt bin ich nur daran interessiert, die erste und die letzte Zeile dieser Abfrage zu erhalten. Ich könnte sie außerhalb der Datenbank, in meiner Anwendung bekommen (und das ist es, was ich eigentlich tue), aber ich fragte mich, ob ich aus Gründen der besseren Leistung nicht nur die beiden Datensätze aus der Datenbank erhalten sollte, die mich wirklich interessieren. 

Und wenn ja, wie kann ich meine Anfrage ändern?

53
kender

[Vorbehalt: Vielleicht nicht der effizienteste Weg, es zu tun]:

(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

Möglicherweise möchten Sie dies versuchen. Möglicherweise sind Sie schneller als zwei Abfragen:

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

Erster Datensatz:

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

Letzter Datensatz:

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

letzter Datensatz:

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

erster Datensatz:

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)

oder

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

Bei allen bisher offengelegten Vorgehensweisen muss der Scanvorgang zweimal durchlaufen werden, eine für die erste und eine für die letzte Zeile.

Mit der Fensterfunktion "ROW_NUMBER () OVER (...)" plus "WITH Queries" können Sie nur einmal scannen und beide Elemente abrufen.

Fensterfunktion: https://www.postgresql.org/docs/9.6/static/functions-window.html

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

Beispiel:

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;

Auf diese Weise werden Sie nur einmal Relationen, Filtrationen und Datenmanipulationen durchführen.

Probieren Sie auf beiden Wegen EXPLAIN ANALYZE aus.

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
);

Verstanden von hier: https://wiki.postgresql.org/wiki/First/last_(aggregate)

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

oder

SELECT        
    MAX(Column) 
FROM            
    TableName
WHERE        
    (Filter)

UNION ALL

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