如何从SQL查询获取第一个和最后一个logging?

我在PostgreSQL中有一个表,我用几个条件运行一个查询,返回多个行,按列之一sorting。 一般来说是这样的:

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

现在我只想从这个查询中获取第一行和最后一行。 我可以把它们放在数据库之外,在我的应用程序内部(这是我实际上做的),但是想知道为了获得更好的性能,我不应该从数据库中得到那些我实际上感兴趣的2条logging。

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

[注意:可能不是最有效的方法]:

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

第一笔logging:

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

最后的logging:

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

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

 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 

最后的logging:

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

第一笔logging:

 SELECT * FROM `aboutus` order by id asc limit 1 
 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) 

要么

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

在所有到目前为止的曝光方式中,都要经过两次扫描,一次是第一行,一次是最后一行。

使用窗口函数“ROW_NUMBER()OVER(…)”加上“WITHQUERY”,您只能扫描一次并获取这两个项目。

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

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

例:

 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; 

这样你就可以只进行一次关系,过滤和数据操作。

两种方式尝试一些EXPLAIN ANALYSE。

 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})); 
 SELECT MIN(Column), MAX(Column), UserId FROM Table_Name WHERE (Conditions) GROUP BY UserId DESC 

要么

 SELECT MAX(Column) FROM TableName WHERE (Filter) UNION ALL SELECT MIN(Column) FROM TableName AS Tablename1 WHERE (Filter) ORDER BY Column 
 -- 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 ); 

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

为什么不使用顺序由asc限制1和反向顺序由desc限制1 ..