Как получить первую и последнюю запись из SQL запроса?
У меня есть таблица в PostgreSQL, Я выполнении запроса с несколькими условиями, который возвращает несколько строк, упорядоченных по одному из столбцов. В общем это:
SELECT <some columns>
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC
теперь меня интересует только получение первой и последней строки из этого запроса. Я мог бы получить их за пределами БД, внутри моего приложения (и это то, что я на самом деле делаю), но мне было интересно, если для лучшей производительности я не должен получать из базы данных только те 2 записи, которые мне действительно интересны в.
и если да, то как мне изменить мой запрос?
10 ответов:
[предостережение: возможно, это не самый эффективный способ сделать это]:
(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)
вы можете попробовать это, потенциально может быть быстрее, чем делать два запроса:
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
первая запись:
SELECT <some columns> FROM mytable <maybe some joins here> WHERE <various conditions> ORDER BY date ASC LIMIT 1
последняя запись:
SELECT <some columns> FROM mytable <maybe some joins here> WHERE <various conditions> ORDER BY date DESC LIMIT 1
последняя запись :
SELECT * FROM `aboutus` order by id desc limit 1
первая запись :
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 (...) "плюс" с запросами", вы можете сканировать только один раз и получить оба элемента.
Функция Окна : 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;
на этом пути вы будете делать отношения, фильтрации и манипуляции с данными только один раз.
попробуйте некоторые объяснить анализ в обоих направлениях.
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 ; $$; -- 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 );
здесь: https://wiki.postgresql.org/wiki/First/last_ (агрегат)