如何从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 ..
?