ultimo - ¿Cómo obtener el primer y último registro de una consulta SQL?
primer y ultimo registro mysql (10)
¿Por qué no utilizar el order by asc limit 1
y el order by desc limit 1
inverso order by desc limit 1
?
Tengo una tabla en PostgreSQL , ejecuto una consulta sobre ella con varias condiciones que devuelve varias filas ordenadas por una de las columnas. En general es:
SELECT <some columns>
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC
Ahora solo estoy interesado en obtener la primera y la última fila de esta consulta. Podría obtenerlos fuera del DB, dentro de mi aplicación (y esto es lo que realmente hago), pero me preguntaba si para obtener un mejor rendimiento no debería obtener de la base de datos solo esos 2 registros que realmente me interesan.
Y si es así, ¿cómo modifico mi consulta?
último registro:
SELECT * FROM `aboutus` order by id desc limit 1
primer registro:
SELECT * FROM `aboutus` order by id asc limit 1
En todas las formas expuestas de hacer hasta ahora, debe pasar por el escáner dos veces, una para la primera fila y otra para la última fila.
Usando la función de ventana "ROW_NUMBER () OVER (...)" más "WITH Queries", puede escanear solo una vez y obtener ambos elementos.
Función de ventana: https://www.postgresql.org/docs/9.6/static/functions-window.html
CON Consultas: https://www.postgresql.org/docs/9.6/static/queries-with.html
Ejemplo:
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;
De esa forma, harás relaciones, filtraciones y manipulación de datos solo una vez.
Pruebe EXPLAIN ANALYZE en ambos sentidos.
Es posible que desee intentar esto, podría ser más rápido que hacer dos consultas:
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
Primer registro:
SELECT <some columns> FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date ASC
LIMIT 1
Último registro:
SELECT <some columns> FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC
LIMIT 1
[Advertencia: podría no ser la forma más eficiente de hacerlo]:
(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)
-- 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
);
Lo tengo desde aquí: https://wiki.postgresql.org/wiki/First/last_(aggregate)
SELECT
MIN(Column), MAX(Column), UserId
FROM
Table_Name
WHERE
(Conditions)
GROUP BY
UserId DESC
o
SELECT
MAX(Column)
FROM
TableName
WHERE
(Filter)
UNION ALL
SELECT
MIN(Column)
FROM
TableName AS Tablename1
WHERE
(Filter)
ORDER BY
Column
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)
o
SELECT * FROM TABLE_NAME WHERE ROWID=(SELECT MIN(ROWID) FROM TABLE_NAME)
OR ROWID=(SELECT MAX(ROWID) FROM TABLE_NAME)
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}));