SQL 如何从sql查询中获取第一条和最后一条记录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1485391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-01 03:48:21  来源:igfitidea点击:

How to get First and Last record from a sql query?

sqlpostgresql

提问by kender

I have a table in PostgreSQL, I run a query on it with several conditions that returns multiple rows, ordered by one of the columns. In general it's:

我在PostgreSQL 中有一个表,我在它上面运行了一个查询,其中有几个条件返回多行,按其中一列排序。一般来说是:

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

Now I'm only interested in getting the first and the last row from this query. I could get them outside of the db, inside my application (and this is what I actually do) but was wondering if for better performance I shouldn't get from the database only those 2 records I'm actually interested in.

现在我只对从这个查询中获取第一行和最后一行感兴趣。我可以将它们放在数据库之外,在我的应用程序中(这就是我实际所做的),但想知道是否为了更好的性能,我不应该只从数据库中获取我真正感兴趣的那 2 条记录。

And if so, how do I modify my query?

如果是这样,我该如何修改我的查询?

回答by Mitch Wheat

[Caveat: Might not be the most efficient way to do it]:

[警告:可能不是最有效的方法]:

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

回答by a_horse_with_no_name

You might want to try this, could potentially be faster than doing two queries:

你可能想试试这个,可能比做两个查询更快:

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

回答by Robo

First record:

第一条记录:

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

Last record:

最后记录:

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

回答by neha

last record :

最后记录:

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

first record :

第一条记录:

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

回答by Natan Medeiros

In all the exposed ways of do until now, must go through scan two times, one for the first row and one for the last row.

到目前为止,在所有暴露的方法中,都必须经过两次扫描,一次扫描第一行,一次扫描最后一行。

Using the Window Function "ROW_NUMBER() OVER (...)" plus "WITH Queries", you can scan only one time and get both items.

使用窗口函数“ROW_NUMBER() OVER (...)”加上“WITH Queries”,您只能扫描一次并获得两项。

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

窗口函数:https: //www.postgresql.org/docs/9.6/static/functions-window.html

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

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

Example:

例子:

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;

On that way you will do relations, filtrations and data manipulation only one time.

通过这种方式,您将只进行一次关系、过滤和数据操作。

Try some EXPLAIN ANALYZE on both ways.

尝试两种方式的解释分析。

回答by sundeepkumar dv

SELECT <rows> FROM TABLE_NAME WHERE ROWID=(SELECT MIN(ROWID) FROM TABLE_NAME) 
UNION
SELECT <rows> FROM TABLE_NAME WHERE ROWID=(SELECT MAX(ROWID) FROM TABLE_NAME)

or

或者

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

回答by Ampolu Balaji

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

回答by Sergey P. aka azure

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


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

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

Got it from here: https://wiki.postgresql.org/wiki/First/last_(aggregate)

从这里得到它:https: //wiki.postgresql.org/wiki/First/last_(aggregate)

回答by Mikhail Sotnikov

In some cases - when not so many columns - useful the WINDOW functions FIRST_VALUE() and LAST_VALUE().

在某些情况下 - 当没有那么多列时 - WINDOW 函数 FIRST_VALUE() 和 LAST_VALUE() 很有用。

 SELECT
    FIRST_VALUE(timestamp) over (ORDER BY timestamp ASC) as created_dt,
    LAST_VALUE(timestamp) over (ORDER BY timestamp ASC) as last_update_dt,
    LAST_VALUE(action) over (ORDER BY timestamp ASC) as last_action
FROM events

This query sort data only once.

此查询仅对数据排序一次。

It can be used for getting fisrt and last rows by some ID

它可用于通过某个 ID 获取第一行和最后一行

SELECT DISTINCT
    order_id,
    FIRST_VALUE(timestamp) over (PARTITION BY order_id ORDER BY timestamp ASC) as created_dt,
    LAST_VALUE(timestamp) over (PARTITION BY order_id ORDER BY timestamp ASC) as last_update_dt,
    LAST_VALUE(action) over (PARTITION BY order_id ORDER BY timestamp ASC) as last_action

FROM events as x

回答by TaTa

How to get the First and Last Record of DB in c#.

如何在c#中获取DB的第一条和最后一条记录。

SELECT TOP 1 * 
  FROM ViewAttendenceReport 
 WHERE EmployeeId = 4 
   AND AttendenceDate >='1/18/2020 00:00:00' 
   AND AttendenceDate <='1/18/2020 23:59:59'
 ORDER BY Intime ASC
 UNION
SELECT TOP 1 * 
  FROM ViewAttendenceReport 
 WHERE EmployeeId = 4 
   AND AttendenceDate >='1/18/2020 00:00:00' 
   AND AttendenceDate <='1/18/2020 23:59:59' 
 ORDER BY OutTime DESC;